diff mbox series

Go patch committed: Handle nil checks with set-and-use temporaries

Message ID CAOyqgcVCLUf0TmS3gJ-OTekA32BqkX7wOANc7j_X8g8mW=bXng@mail.gmail.com
State New
Headers show
Series Go patch committed: Handle nil checks with set-and-use temporaries | expand

Commit Message

Ian Lance Taylor Dec. 6, 2017, 1:32 p.m. UTC
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
diff mbox series

Patch

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;