From 4c6f5562dce997c013340fb5d6891d777efb99be Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 6 Dec 2017 13:32:06 +0000 Subject: [PATCH] compiler: handle set-and-use-temp in nilcheck code Change the 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). Reviewed-on: https://go-review.googlesource.com/81915 From-SVN: r255442 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index e0d606c7e26..b185c9e59c3 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index e9b86831dc9..219b16361ed 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -4455,10 +4455,23 @@ Unary_expression::do_get_backend(Translate_context* context) 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(Translate_context* context) 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; -- 2.30.2