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;