compiler: handle set-and-use-temp in nilcheck code
authorIan Lance Taylor <ian@gcc.gnu.org>
Wed, 6 Dec 2017 13:32:06 +0000 (13:32 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 6 Dec 2017 13:32:06 +0000 (13:32 +0000)
    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
gcc/go/gofrontend/expressions.cc

index e0d606c..b185c9e 100644 (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.
index e9b8683..219b163 100644 (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;