This is hopefully the last attempt to fix the libgo breakage. This time around I really think I got to the bottom of the problem. The issue is that the Go FE defines the __builtin_trap call, but doesn't set the TREE_THIS_VOLATILE flag on it. That's bad because then this call isn't gimple_call_noreturn_p and the cgraph cleanup code can't do its job properly.
Bootstrapped/regtested on x86_64-linux. Now, I don't know the Go patch process here. Should I just wait for you Ian to commit the patch? (Yeah, I think I don't need the ChangeLog entry.) 2015-08-24 Marek Polacek <pola...@redhat.com> PR tree-optimization/67284 * go-gcc.cc (Gcc_backend::define_builtin): Add NORETURN_P default argument. Set TREE_THIS_VOLATILE. (Gcc_backend::Gcc_backend): Mark __builtin_trap as a noreturn call. diff --git gcc/go/go-gcc.cc gcc/go/go-gcc.cc index 6f274fc..aabcd98 100644 --- gcc/go/go-gcc.cc +++ gcc/go/go-gcc.cc @@ -498,7 +498,7 @@ class Gcc_backend : public Backend private: void define_builtin(built_in_function bcode, const char* name, const char* libname, - tree fntype, bool const_p); + tree fntype, bool const_p, bool noreturn_p = false); // A mapping of the GCC built-ins exposed to GCCGo. std::map<std::string, Bfunction*> builtin_functions_; @@ -675,7 +675,7 @@ Gcc_backend::Gcc_backend() // cases. this->define_builtin(BUILT_IN_TRAP, "__builtin_trap", NULL, build_function_type(void_type_node, void_list_node), - false); + false, true); } // Get an unnamed integer type. @@ -3095,15 +3095,19 @@ Gcc_backend::write_global_definitions( // LIBNAME is the name of the corresponding library function, and is // NULL if there isn't one. FNTYPE is the type of the function. // CONST_P is true if the function has the const attribute. +// NORETURN_P is true if the function has the noreturn attribute. void Gcc_backend::define_builtin(built_in_function bcode, const char* name, - const char* libname, tree fntype, bool const_p) + const char* libname, tree fntype, bool const_p, + bool noreturn_p) { tree decl = add_builtin_function(name, fntype, bcode, BUILT_IN_NORMAL, libname, NULL_TREE); if (const_p) TREE_READONLY(decl) = 1; + if (noreturn_p) + TREE_THIS_VOLATILE(decl) = 1; set_builtin_decl(bcode, decl, true); this->builtin_functions_[name] = this->make_function(decl); if (libname != NULL) @@ -3112,6 +3116,8 @@ Gcc_backend::define_builtin(built_in_function bcode, const char* name, NULL, NULL_TREE); if (const_p) TREE_READONLY(decl) = 1; + if (noreturn_p) + TREE_THIS_VOLATILE(decl) = 1; this->builtin_functions_[libname] = this->make_function(decl); } } Marek