This patch to the Go frontend adds result parameter names for inlinable functions. An inlinable function body may need to refer to result parameters, so each result parameter needs a name. We already give them all names in start_function (via create_result_variables). Change the export data so that for an inlinable function we use those names for the function declaration's result parameters. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline.
Ian
Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 266531) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -21cf8069ceb078de54cc43ac25c9c89bd15cba56 +5d0c788cd6099c2bb28bb0ff6a04d94006fbfca8 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: gcc/go/gofrontend/gogo.cc =================================================================== --- gcc/go/gofrontend/gogo.cc (revision 266530) +++ gcc/go/gofrontend/gogo.cc (working copy) @@ -5487,7 +5487,7 @@ Function::export_func(Export* exp, const Block* block = NULL; if (this->export_for_inlining()) block = this->block_; - Function::export_func_with_type(exp, name, this->type_, + Function::export_func_with_type(exp, name, this->type_, this->results_, this->is_method() && this->nointerface(), block, this->location_); } @@ -5496,8 +5496,9 @@ Function::export_func(Export* exp, const void Function::export_func_with_type(Export* exp, const std::string& name, - const Function_type* fntype, bool nointerface, - Block* block, Location loc) + const Function_type* fntype, + Function::Results* result_vars, + bool nointerface, Block* block, Location loc) { exp->write_c_string("func "); @@ -5549,31 +5550,45 @@ Function::export_func_with_type(Export* } exp->write_c_string(")"); - const Typed_identifier_list* results = fntype->results(); - if (results != NULL) + const Typed_identifier_list* result_decls = fntype->results(); + if (result_decls != NULL) { - if (results->size() == 1 && results->begin()->name().empty()) + if (result_decls->size() == 1 + && result_decls->begin()->name().empty() + && block == NULL) { exp->write_c_string(" "); - exp->write_type(results->begin()->type()); + exp->write_type(result_decls->begin()->type()); } else { exp->write_c_string(" ("); bool first = true; - for (Typed_identifier_list::const_iterator p = results->begin(); - p != results->end(); - ++p) + Results::const_iterator pr; + if (result_vars != NULL) + pr = result_vars->begin(); + for (Typed_identifier_list::const_iterator pd = result_decls->begin(); + pd != result_decls->end(); + ++pd) { if (first) first = false; else exp->write_c_string(", "); - exp->write_name(p->name()); - exp->write_escape(p->note()); + // We only use pr->name, which may be artificial, if + // need it for inlining. + if (block == NULL || result_vars == NULL) + exp->write_name(pd->name()); + else + exp->write_name((*pr)->name()); + exp->write_escape(pd->note()); exp->write_c_string(" "); - exp->write_type(p->type()); + exp->write_type(pd->type()); + if (result_vars != NULL) + ++pr; } + if (result_vars != NULL) + go_assert(pr == result_vars->end()); exp->write_c_string(")"); } } Index: gcc/go/gofrontend/gogo.h =================================================================== --- gcc/go/gofrontend/gogo.h (revision 266530) +++ gcc/go/gofrontend/gogo.h (working copy) @@ -1513,8 +1513,8 @@ class Function // Export a function with a type. static void export_func_with_type(Export*, const std::string& name, - const Function_type*, bool nointerface, Block* block, - Location); + const Function_type*, Results*, bool nointerface, + Block* block, Location); // Import a function. static void @@ -1740,7 +1740,7 @@ class Function_declaration void export_func(Export* exp, const std::string& name) const { - Function::export_func_with_type(exp, name, this->fntype_, + Function::export_func_with_type(exp, name, this->fntype_, NULL, this->is_method() && this->nointerface(), NULL, this->location_); }