Skip to content

Commit

Permalink
compiler: fix evaluation order of LHS index expressions
Browse files Browse the repository at this point in the history
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

Change-Id: I90e17ada43df58d439c060344f9224dbe1e7dacd
Reviewed-on: https://go-review.googlesource.com/123155
Reviewed-by: Than McIntosh <[email protected]>
  • Loading branch information
ianlancetaylor committed Jul 11, 2018
1 parent 8ad67a7 commit ea7ac77
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 20 deletions.
14 changes: 14 additions & 0 deletions go/expressions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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*
Expand Down
28 changes: 8 additions & 20 deletions go/expressions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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*);
Expand Down Expand Up @@ -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.

Expand Down

0 comments on commit ea7ac77

Please sign in to comment.