* Go patch committed: Avoid middle-end control flow warnings
@ 2017-12-02 0:39 Ian Lance Taylor
0 siblings, 0 replies; only message in thread
From: Ian Lance Taylor @ 2017-12-02 0:39 UTC (permalink / raw)
To: gcc-patches, gofrontend-dev
[-- Attachment #1: Type: text/plain, Size: 753 bytes --]
The GCC middle-end has started emitting "control reaches end of
non-void function" warnings. This are not too useful for Go, which
implements its own error for this in the frontend. Avoid the
middle-end warnings 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. This fixes
https://golang.org/issue/22767. Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu. Committed to mainline.
Ian
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.
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 7539 bytes --]
Index: gcc/go/go-gcc.cc
===================================================================
--- gcc/go/go-gcc.cc (revision 255340)
+++ gcc/go/go-gcc.cc (working copy)
@@ -486,7 +486,8 @@ class Gcc_backend : public Backend
Bfunction*
function(Btype* fntype, const std::string& name, const std::string& asm_name,
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*
function_defer_statement(Bfunction* function, Bexpression* undefer,
@@ -760,6 +761,12 @@ Gcc_backend::Gcc_backend()
const_ptr_type_node,
NULL_TREE),
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.
@@ -3012,8 +3019,8 @@ Bfunction*
Gcc_backend::function(Btype* fntype, const std::string& name,
const std::string& asm_name, bool is_visible,
bool is_declaration, bool is_inlinable,
- bool disable_split_stack, bool in_unique_section,
- Location location)
+ bool disable_split_stack, bool does_not_return,
+ bool in_unique_section, Location location)
{
tree functype = fntype->get_tree();
if (functype != error_mark_node)
@@ -3049,6 +3056,8 @@ Gcc_backend::function(Btype* fntype, con
tree attr = get_identifier ("no_split_stack");
DECL_ATTRIBUTES(decl) = tree_cons(attr, NULL_TREE, NULL_TREE);
}
+ if (does_not_return)
+ TREE_THIS_VOLATILE(decl) = 1;
if (in_unique_section)
resolve_unique_section(decl, 0, 1);
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE (revision 255340)
+++ gcc/go/gofrontend/MERGE (working copy)
@@ -1,4 +1,4 @@
-8cd42a3e9e0e618bb09e67be73f7d2f2477a0faa
+1949a203fca0c8bde6f2690ebc36427c5e3953c7
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
Index: gcc/go/gofrontend/backend.h
===================================================================
--- gcc/go/gofrontend/backend.h (revision 255340)
+++ gcc/go/gofrontend/backend.h (working copy)
@@ -711,12 +711,15 @@ class Backend
// IS_INLINABLE is true if the function can be inlined.
// DISABLE_SPLIT_STACK is true if this function may not split the stack; this
// 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
// location if possible; this is used for field tracking.
virtual Bfunction*
function(Btype* fntype, const std::string& name, const std::string& asm_name,
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
// be a statement that looks like this in C++:
Index: gcc/go/gofrontend/gogo.cc
===================================================================
--- gcc/go/gofrontend/gogo.cc (revision 255340)
+++ gcc/go/gofrontend/gogo.cc (working copy)
@@ -711,7 +711,7 @@ Gogo::init_imports(std::vector<Bstatemen
Bfunction* pfunc = this->backend()->function(fntype, user_name, init_name,
true, true, true, false,
- false, unknown_loc);
+ false, false, unknown_loc);
Bexpression* pfunc_code =
this->backend()->function_code_expression(pfunc, unknown_loc);
Bexpression* pfunc_call =
@@ -5435,8 +5435,8 @@ Function::get_or_make_decl(Gogo* gogo, N
this->fndecl_ =
gogo->backend()->function(functype, no->get_id(gogo), asm_name,
is_visible, false, is_inlinable,
- disable_split_stack, in_unique_section,
- this->location());
+ disable_split_stack, false,
+ in_unique_section, this->location());
}
return this->fndecl_;
}
@@ -5448,6 +5448,8 @@ Function_declaration::get_or_make_decl(G
{
if (this->fndecl_ == NULL)
{
+ bool does_not_return = false;
+
// Let Go code use an asm declaration to pick up a builtin
// function.
if (!this->asm_name_.empty())
@@ -5459,6 +5461,10 @@ Function_declaration::get_or_make_decl(G
this->fndecl_ = builtin_decl;
return this->fndecl_;
}
+
+ if (this->asm_name_ == "runtime.gopanic"
+ || this->asm_name_ == "__go_runtime_error")
+ does_not_return = true;
}
std::string asm_name;
@@ -5475,8 +5481,8 @@ Function_declaration::get_or_make_decl(G
Btype* functype = this->fntype_->get_backend_fntype(gogo);
this->fndecl_ =
gogo->backend()->function(functype, no->get_id(gogo), asm_name,
- true, true, true, false, false,
- this->location());
+ true, true, true, false, does_not_return,
+ false, this->location());
}
return this->fndecl_;
Index: gcc/go/gofrontend/runtime.def
===================================================================
--- gcc/go/gofrontend/runtime.def (revision 255340)
+++ gcc/go/gofrontend/runtime.def (working copy)
@@ -363,6 +363,9 @@ DEF_GO_RUNTIME(PRINTNL, "runtime.printnl
DEF_GO_RUNTIME(FIELDTRACK, "__go_fieldtrack", P1(POINTER), R0())
+// Unreachable code.
+DEF_GO_RUNTIME(UNREACHABLE, "__builtin_unreachable", P0(), R0())
+
// Remove helper macros.
#undef ABFT6
#undef ABFT2
Index: gcc/go/gofrontend/statements.cc
===================================================================
--- gcc/go/gofrontend/statements.cc (revision 255340)
+++ gcc/go/gofrontend/statements.cc (working copy)
@@ -4866,8 +4866,8 @@ Select_clauses::get_backend(Translate_co
Location location)
{
size_t count = this->clauses_.size();
- std::vector<std::vector<Bexpression*> > cases(count);
- std::vector<Bstatement*> clauses(count);
+ std::vector<std::vector<Bexpression*> > cases(count + 1);
+ std::vector<Bstatement*> clauses(count + 1);
Type* int_type = Type::lookup_integer_type("int");
@@ -4905,10 +4905,15 @@ Select_clauses::get_backend(Translate_co
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;
statements.reserve(2);
- Bfunction* bfunction = context->function()->func_value()->get_decl();
Bstatement* switch_stmt = context->backend()->switch_statement(bfunction,
bcall,
cases,
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2017-12-02 0:39 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-02 0:39 Go patch committed: Avoid middle-end control flow warnings Ian Lance Taylor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).