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
This commit is contained in:
Ian Lance Taylor 2017-12-06 13:32:06 +00:00
parent 40242256f1
commit 4c6f5562dc
2 changed files with 16 additions and 3 deletions

View file

@ -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.

View file

@ -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;