Commit 9638589f by Ian Lance Taylor Committed by Ian Lance Taylor

compiler: avoid GCC middle-end control warnings

    
    GCC has started emitting "control reaches end of non-void function"
    warnings. Avoid them for Go by 1) marking the builtin function panic
    and the compiler-generated function __go_runtime_error as not
    returning and 2) adding a default case to the switch used for select
    statements that simply calls __builtin_unreachable.
    
    Fixes golang/go#22767
    
    Reviewed-on: https://go-review.googlesource.com/80416

	* go-gcc.cc (Gcc_backend::Gcc_backend): Define
	__builtin_unreachable.
	(Gcc_backend::function): Add does_not_return parameter.

From-SVN: r255346
parent d7d5f241
2017-12-01 Ian Lance Taylor <iant@golang.org>
* go-gcc.cc (Gcc_backend::Gcc_backend): Define
__builtin_unreachable.
(Gcc_backend::function): Add does_not_return parameter.
2017-12-01 Than McIntosh <thanm@google.com> 2017-12-01 Than McIntosh <thanm@google.com>
* go-c.h (go_create_gogo_args): Add nil_check_size_threshold * go-c.h (go_create_gogo_args): Add nil_check_size_threshold
......
...@@ -486,7 +486,8 @@ class Gcc_backend : public Backend ...@@ -486,7 +486,8 @@ class Gcc_backend : public Backend
Bfunction* Bfunction*
function(Btype* fntype, const std::string& name, const std::string& asm_name, function(Btype* fntype, const std::string& name, const std::string& asm_name,
bool is_visible, bool is_declaration, bool is_inlinable, bool is_visible, bool is_declaration, bool is_inlinable,
bool disable_split_stack, bool in_unique_section, Location); bool disable_split_stack, bool does_not_return,
bool in_unique_section, Location);
Bstatement* Bstatement*
function_defer_statement(Bfunction* function, Bexpression* undefer, function_defer_statement(Bfunction* function, Bexpression* undefer,
...@@ -760,6 +761,12 @@ Gcc_backend::Gcc_backend() ...@@ -760,6 +761,12 @@ Gcc_backend::Gcc_backend()
const_ptr_type_node, const_ptr_type_node,
NULL_TREE), NULL_TREE),
false, false); false, false);
// The compiler uses __builtin_unreachable for cases that can not
// occur.
this->define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL,
build_function_type(void_type_node, void_list_node),
true, true);
} }
// Get an unnamed integer type. // Get an unnamed integer type.
...@@ -3012,8 +3019,8 @@ Bfunction* ...@@ -3012,8 +3019,8 @@ Bfunction*
Gcc_backend::function(Btype* fntype, const std::string& name, Gcc_backend::function(Btype* fntype, const std::string& name,
const std::string& asm_name, bool is_visible, const std::string& asm_name, bool is_visible,
bool is_declaration, bool is_inlinable, bool is_declaration, bool is_inlinable,
bool disable_split_stack, bool in_unique_section, bool disable_split_stack, bool does_not_return,
Location location) bool in_unique_section, Location location)
{ {
tree functype = fntype->get_tree(); tree functype = fntype->get_tree();
if (functype != error_mark_node) if (functype != error_mark_node)
...@@ -3049,6 +3056,8 @@ Gcc_backend::function(Btype* fntype, const std::string& name, ...@@ -3049,6 +3056,8 @@ Gcc_backend::function(Btype* fntype, const std::string& name,
tree attr = get_identifier ("no_split_stack"); tree attr = get_identifier ("no_split_stack");
DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE); DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE);
} }
if (does_not_return)
TREE_THIS_VOLATILE(decl) = 1;
if (in_unique_section) if (in_unique_section)
resolve_unique_section(decl, 0, 1); resolve_unique_section(decl, 0, 1);
......
8cd42a3e9e0e618bb09e67be73f7d2f2477a0faa 1949a203fca0c8bde6f2690ebc36427c5e3953c7
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -711,12 +711,15 @@ class Backend ...@@ -711,12 +711,15 @@ class Backend
// IS_INLINABLE is true if the function can be inlined. // IS_INLINABLE is true if the function can be inlined.
// DISABLE_SPLIT_STACK is true if this function may not split the stack; this // DISABLE_SPLIT_STACK is true if this function may not split the stack; this
// is used for the implementation of recover. // is used for the implementation of recover.
// DOES_NOT_RETURN is true for a function that does not return; this is used
// for the implementation of panic.
// IN_UNIQUE_SECTION is true if this function should be put into a unique // IN_UNIQUE_SECTION is true if this function should be put into a unique
// location if possible; this is used for field tracking. // location if possible; this is used for field tracking.
virtual Bfunction* virtual Bfunction*
function(Btype* fntype, const std::string& name, const std::string& asm_name, function(Btype* fntype, const std::string& name, const std::string& asm_name,
bool is_visible, bool is_declaration, bool is_inlinable, bool is_visible, bool is_declaration, bool is_inlinable,
bool disable_split_stack, bool in_unique_section, Location) = 0; bool disable_split_stack, bool does_not_return,
bool in_unique_section, Location) = 0;
// Create a statement that runs all deferred calls for FUNCTION. This should // Create a statement that runs all deferred calls for FUNCTION. This should
// be a statement that looks like this in C++: // be a statement that looks like this in C++:
......
...@@ -711,7 +711,7 @@ Gogo::init_imports(std::vector<Bstatement*>& init_stmts, Bfunction *bfunction) ...@@ -711,7 +711,7 @@ Gogo::init_imports(std::vector<Bstatement*>& init_stmts, Bfunction *bfunction)
Bfunction* pfunc = this->backend()->function(fntype, user_name, init_name, Bfunction* pfunc = this->backend()->function(fntype, user_name, init_name,
true, true, true, false, true, true, true, false,
false, unknown_loc); false, false, unknown_loc);
Bexpression* pfunc_code = Bexpression* pfunc_code =
this->backend()->function_code_expression(pfunc, unknown_loc); this->backend()->function_code_expression(pfunc, unknown_loc);
Bexpression* pfunc_call = Bexpression* pfunc_call =
...@@ -5435,8 +5435,8 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no) ...@@ -5435,8 +5435,8 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
this->fndecl_ = this->fndecl_ =
gogo->backend()->function(functype, no->get_id(gogo), asm_name, gogo->backend()->function(functype, no->get_id(gogo), asm_name,
is_visible, false, is_inlinable, is_visible, false, is_inlinable,
disable_split_stack, in_unique_section, disable_split_stack, false,
this->location()); in_unique_section, this->location());
} }
return this->fndecl_; return this->fndecl_;
} }
...@@ -5448,6 +5448,8 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no) ...@@ -5448,6 +5448,8 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no)
{ {
if (this->fndecl_ == NULL) if (this->fndecl_ == NULL)
{ {
bool does_not_return = false;
// Let Go code use an asm declaration to pick up a builtin // Let Go code use an asm declaration to pick up a builtin
// function. // function.
if (!this->asm_name_.empty()) if (!this->asm_name_.empty())
...@@ -5459,6 +5461,10 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no) ...@@ -5459,6 +5461,10 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no)
this->fndecl_ = builtin_decl; this->fndecl_ = builtin_decl;
return this->fndecl_; return this->fndecl_;
} }
if (this->asm_name_ == "runtime.gopanic"
|| this->asm_name_ == "__go_runtime_error")
does_not_return = true;
} }
std::string asm_name; std::string asm_name;
...@@ -5475,8 +5481,8 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no) ...@@ -5475,8 +5481,8 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no)
Btype* functype = this->fntype_->get_backend_fntype(gogo); Btype* functype = this->fntype_->get_backend_fntype(gogo);
this->fndecl_ = this->fndecl_ =
gogo->backend()->function(functype, no->get_id(gogo), asm_name, gogo->backend()->function(functype, no->get_id(gogo), asm_name,
true, true, true, false, false, true, true, true, false, does_not_return,
this->location()); false, this->location());
} }
return this->fndecl_; return this->fndecl_;
......
...@@ -363,6 +363,9 @@ DEF_GO_RUNTIME(PRINTNL, "runtime.printnl", P0(), R0()) ...@@ -363,6 +363,9 @@ DEF_GO_RUNTIME(PRINTNL, "runtime.printnl", P0(), R0())
DEF_GO_RUNTIME(FIELDTRACK, "__go_fieldtrack", P1(POINTER), R0()) DEF_GO_RUNTIME(FIELDTRACK, "__go_fieldtrack", P1(POINTER), R0())
// Unreachable code.
DEF_GO_RUNTIME(UNREACHABLE, "__builtin_unreachable", P0(), R0())
// Remove helper macros. // Remove helper macros.
#undef ABFT6 #undef ABFT6
#undef ABFT2 #undef ABFT2
......
...@@ -4866,8 +4866,8 @@ Select_clauses::get_backend(Translate_context* context, ...@@ -4866,8 +4866,8 @@ Select_clauses::get_backend(Translate_context* context,
Location location) Location location)
{ {
size_t count = this->clauses_.size(); size_t count = this->clauses_.size();
std::vector<std::vector<Bexpression*> > cases(count); std::vector<std::vector<Bexpression*> > cases(count + 1);
std::vector<Bstatement*> clauses(count); std::vector<Bstatement*> clauses(count + 1);
Type* int_type = Type::lookup_integer_type("int"); Type* int_type = Type::lookup_integer_type("int");
...@@ -4905,10 +4905,15 @@ Select_clauses::get_backend(Translate_context* context, ...@@ -4905,10 +4905,15 @@ Select_clauses::get_backend(Translate_context* context,
return context->backend()->expression_statement(bfunction, bcall); return context->backend()->expression_statement(bfunction, bcall);
} }
Bfunction* bfunction = context->function()->func_value()->get_decl();
Expression* crash = Runtime::make_call(Runtime::UNREACHABLE, location, 0);
Bexpression* bcrash = crash->get_backend(context);
clauses[count] = context->backend()->expression_statement(bfunction, bcrash);
std::vector<Bstatement*> statements; std::vector<Bstatement*> statements;
statements.reserve(2); statements.reserve(2);
Bfunction* bfunction = context->function()->func_value()->get_decl();
Bstatement* switch_stmt = context->backend()->switch_statement(bfunction, Bstatement* switch_stmt = context->backend()->switch_statement(bfunction,
bcall, bcall,
cases, cases,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment