This patch by Than McIntosh changes the Go frontend code in Unary_expression::do_get_backend that introduces explicit nil checks for dereference operations to special case set-and-use-temporary expressions. For this case it is better to generate an explicit reference of the temp in the final conditional (avoids introducing tree sharing). 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 255400) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -297cf346f2400274946650ab9ecd039427fc986b +d16e370c93e2866a961847a15f5001413e66d179 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 255340) +++ gcc/go/gofrontend/expressions.cc (working copy) @@ -4455,10 +4455,23 @@ Unary_expression::do_get_backend(Transla case NIL_CHECK_NEEDED: { go_assert(this->expr_->is_variable()); + + // If we're nil-checking the result of a set-and-use-temporary + // expression, then pick out the target temp and use that + // for the final result of the conditional. + Bexpression* tbexpr = bexpr; + Bexpression* ubexpr = bexpr; + Set_and_use_temporary_expression* sut = + this->expr_->set_and_use_temporary_expression(); + if (sut != NULL) { + Temporary_statement* temp = sut->temporary(); + Bvariable* bvar = temp->get_backend_variable(context); + ubexpr = gogo->backend()->var_expression(bvar, loc); + } Bexpression* nil = Expression::make_nil(loc)->get_backend(context); Bexpression* compare = - gogo->backend()->binary_expression(OPERATOR_EQEQ, bexpr, + gogo->backend()->binary_expression(OPERATOR_EQEQ, tbexpr, nil, loc); Bexpression* crash = gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE, @@ -4466,7 +4479,7 @@ Unary_expression::do_get_backend(Transla Bfunction* bfn = context->function()->func_value()->get_decl(); bexpr = gogo->backend()->conditional_expression(bfn, btype, compare, - crash, bexpr, + crash, ubexpr, loc); known_valid = true; break;