This patch to the Go frontend by Than McIntosh fixes an lvalue/rvalue context mixup Set_and_use_temporary_expression's do_get_backend() method, and enhances Mark_lvalue_varexprs to handle conversions and temporary reference expressions, since occasionally the front end emits code such as "deref(conv(tempref)) = ...". 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 249033) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -82961ce59e8bb02598d963d2a05b3acca860d9dd +d4875b19266d5f726e0e32843b903075f5c50b4c The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: gcc/go/gofrontend/expressions.cc =================================================================== --- gcc/go/gofrontend/expressions.cc (revision 249029) +++ gcc/go/gofrontend/expressions.cc (working copy) @@ -962,7 +962,7 @@ Set_and_use_temporary_expression::do_get Location loc = this->location(); Gogo* gogo = context->gogo(); Bvariable* bvar = this->statement_->get_backend_variable(context); - Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, VE_rvalue, loc); + Bexpression* lvar_ref = gogo->backend()->var_expression(bvar, VE_lvalue, loc); Named_object* fn = context->function(); go_assert(fn != NULL); @@ -970,7 +970,7 @@ Set_and_use_temporary_expression::do_get Bexpression* bexpr = this->expr_->get_backend(context); Bstatement* set = gogo->backend()->assignment_statement(bfn, lvar_ref, bexpr, loc); - Bexpression* var_ref = gogo->backend()->var_expression(bvar, VE_lvalue, loc); + Bexpression* var_ref = gogo->backend()->var_expression(bvar, VE_rvalue, loc); Bexpression* ret = gogo->backend()->compound_expression(set, var_ref, loc); return ret; } Index: gcc/go/gofrontend/statements.cc =================================================================== --- gcc/go/gofrontend/statements.cc (revision 249028) +++ gcc/go/gofrontend/statements.cc (working copy) @@ -912,6 +912,21 @@ int Mark_lvalue_varexprs::expression(Exp if (ue && ue->op() == OPERATOR_MULT) return TRAVERSE_CONTINUE; + Type_conversion_expression* ce = e->conversion_expression(); + if (ce) + return TRAVERSE_CONTINUE; + + Temporary_reference_expression* tre = + e->temporary_reference_expression(); + if (tre) + { + tre = new Temporary_reference_expression(tre->statement(), + tre->location()); + *ppexpr = tre; + tre->set_is_lvalue(); + return TRAVERSE_EXIT; + } + return TRAVERSE_EXIT; }