compiler: fix evaluation order of LHS index expressions
authorIan Lance Taylor <ian@gcc.gnu.org>
Wed, 11 Jul 2018 14:22:12 +0000 (14:22 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 11 Jul 2018 14:22:12 +0000 (14:22 +0000)
    The spec says that when an index expression appears on the left hand
    side of an assignment, the operands should be evaluated. The
    gofrontend code was assuming that that only referred to the index
    operand. But discussion of https://golang.org/issue/23188 has
    clarified that this means both the slice/map/string operand and the
    index operand. Adjust the gofrontend code accordingly.

    Fixes golang/go#23188

    Reviewed-on: https://go-review.googlesource.com/123155

From-SVN: r262554

gcc/go/gofrontend/MERGE
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h

index 8a63818951beabd1851cce03fb38632c68db8587..7d5c0aa7e0d0b8e1a4d9a3f3286823116c3528e3 100644 (file)
@@ -1,4 +1,4 @@
-8ad67a72a4fa59efffc891e73ecf10020e3c565d
+ea7ac7784791dca517b6681a02c39c11bf136755
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 89b265b9b6bba6606e6e31cc6374e1f516a808fd..e7d0b7522195acf946d3b48a21feacd99647f7c7 100644 (file)
@@ -10898,6 +10898,20 @@ Array_index_expression::do_check_types(Gogo*)
     }
 }
 
+// The subexpressions of an array index must be evaluated in order.
+// If this is indexing into an array, rather than a slice, then only
+// the index should be evaluated.  Since this is called for values on
+// the left hand side of an assigment, evaluating the array, meaning
+// copying the array, will cause a different array to be modified.
+
+bool
+Array_index_expression::do_must_eval_subexpressions_in_order(
+    int* skip) const
+{
+  *skip = this->array_->type()->is_slice_type() ? 0 : 1;
+  return true;
+}
+
 // Flatten array indexing by using temporary variables for slices and indexes.
 
 Expression*
index a58c79c7b1512c7f99e47bbe3cb6831b18227159..5fa417159462b7d0e97c54576051a1ce36c03838 100644 (file)
@@ -2771,12 +2771,10 @@ class Index_expression : public Parser_expression
                                this->location());
   }
 
+  // This shouldn't be called--we don't know yet.
   bool
-  do_must_eval_subexpressions_in_order(int* skip) const
-  {
-    *skip = 1;
-    return true;
-  }
+  do_must_eval_subexpressions_in_order(int*) const
+  { go_unreachable(); }
 
   void
   do_dump_expression(Ast_dump_context*) const;
@@ -2882,11 +2880,7 @@ class Array_index_expression : public Expression
   }
 
   bool
-  do_must_eval_subexpressions_in_order(int* skip) const
-  {
-    *skip = 1;
-    return true;
-  }
+  do_must_eval_subexpressions_in_order(int* skip) const;
 
   bool
   do_is_addressable() const;
@@ -2965,11 +2959,8 @@ class String_index_expression : public Expression
   }
 
   bool
-  do_must_eval_subexpressions_in_order(int* skip) const
-  {
-    *skip = 1;
-    return true;
-  }
+  do_must_eval_subexpressions_in_order(int*) const
+  { return true; }
 
   Bexpression*
   do_get_backend(Translate_context*);
@@ -3052,11 +3043,8 @@ class Map_index_expression : public Expression
   }
 
   bool
-  do_must_eval_subexpressions_in_order(int* skip) const
-  {
-    *skip = 1;
-    return true;
-  }
+  do_must_eval_subexpressions_in_order(int*) const
+  { return true; }
 
   // A map index expression is an lvalue but it is not addressable.