In Go a function named _ does not need to be emitted, but it does need to be compiled up to the point of the middle-end in case it has any errors. The gccgo frontend was just skipping the function entirely. This patch from Rémy Oudompheng fixes that. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline and 4.8 branch.
Ian
diff -r c85c21ae9a6c go/gogo-tree.cc --- a/go/gogo-tree.cc Thu Jun 20 17:27:09 2013 -0700 +++ b/go/gogo-tree.cc Fri Jun 21 10:53:04 2013 -0700 @@ -829,6 +829,14 @@ } } + // Skip blank named functions. + if (no->is_function() && no->func_value()->is_sink()) + { + --i; + --count; + continue; + } + if (!no->is_variable()) { vec[i] = no->get_tree(this, NULL); diff -r c85c21ae9a6c go/gogo.cc --- a/go/gogo.cc Thu Jun 20 17:27:09 2013 -0700 +++ b/go/gogo.cc Fri Jun 21 10:53:04 2013 -0700 @@ -819,7 +819,8 @@ char buf[30]; snprintf(buf, sizeof buf, ".$sink%d", sink_count); ++sink_count; - ret = Named_object::make_function(buf, NULL, function); + ret = this->package_->bindings()->add_function(buf, NULL, function); + ret->func_value()->set_is_sink(); } else if (!type->is_method()) { @@ -3253,8 +3254,8 @@ : type_(type), enclosing_(enclosing), results_(NULL), closure_var_(NULL), block_(block), location_(location), labels_(), local_type_count_(0), descriptor_(NULL), fndecl_(NULL), defer_stack_(NULL), - results_are_named_(false), nointerface_(false), calls_recover_(false), - is_recover_thunk_(false), has_recover_thunk_(false), + is_sink_(false), results_are_named_(false), nointerface_(false), + calls_recover_(false), is_recover_thunk_(false), has_recover_thunk_(false), in_unique_section_(false), is_descriptor_wrapper_(false) { } diff -r c85c21ae9a6c go/gogo.h --- a/go/gogo.h Thu Jun 20 17:27:09 2013 -0700 +++ b/go/gogo.h Fri Jun 21 10:53:04 2013 -0700 @@ -911,6 +911,14 @@ result_variables() { return this->results_; } + bool + is_sink() const + { return this->is_sink_; } + + void + set_is_sink() + { this->is_sink_ = true; } + // Whether the result variables have names. bool results_are_named() const @@ -1167,6 +1175,8 @@ // distinguish the defer stack for one function from another. This // is NULL unless we actually need a defer stack. Temporary_statement* defer_stack_; + // True if this function is sink-named. No code is generated. + bool is_sink_ : 1; // True if the result variables are named. bool results_are_named_ : 1; // True if this method should not be included in the type descriptor.