Go patch committed: Fix double evaluation when using interface field expression

Message ID CAOyqgcXUiRJvhS9X5jaqvM=g2FXr0JbDru02sqmiJXKMwdqzyA@mail.gmail.com
State New
Headers show
Series
  • Go patch committed: Fix double evaluation when using interface field expression
Related show

Commit Message

Ian Lance Taylor July 10, 2018, 12:55 a.m.
This patch to the Go frontend by Cherry Zhang fixes the compiler to
avoid a double evaluation of an interface field expression.  In
Interface_field_reference_expression, the interface expression is used
in two places, so a temporary variable is used.  Previously, we used a
Set_and_use_temporary_expression, which, when evaluated twice, causes
double evaluation of the underlying expression.  Fix by setting the
temporary once and use Temporary_reference_expression instead.

This fixes https://golang.org/issue/26248.  The test case for this is
in https://golang.org/cl/122757.

Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 262313)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-94738979a3422e845acf358a766aabf8b9275d43
+8ad67a72a4fa59efffc891e73ecf10020e3c565d
 
 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 262312)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -11886,10 +11886,9 @@  Interface_field_reference_expression::do
   if (!this->expr_->is_variable())
     {
       Temporary_statement* temp =
-	Statement::make_temporary(this->expr_->type(), NULL, this->location());
+	Statement::make_temporary(NULL, this->expr_, this->location());
       inserter->insert(temp);
-      this->expr_ = Expression::make_set_and_use_temporary(temp, this->expr_,
-							   this->location());
+      this->expr_ = Expression::make_temporary_reference(temp, this->location());
     }
   return this;
 }