aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-04-24 16:24:38 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-04-24 16:24:38 +0000
commit5ada012290883e98d76a3ac6dcd34e56d50057e3 (patch)
tree77d2ef18af6f3cc34a841faf5a5d20309be8ec31 /gcc/go
parent24d5b351b1bb9d2fd66202cbf76857c404e06e85 (diff)
downloadgcc-5ada012290883e98d76a3ac6dcd34e56d50057e3.zip
gcc-5ada012290883e98d76a3ac6dcd34e56d50057e3.tar.gz
gcc-5ada012290883e98d76a3ac6dcd34e56d50057e3.tar.bz2
compiler: Fix order of evalation for m[0] = len(m) when m is a map.
From-SVN: r186772
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/gogo.cc18
1 files changed, 12 insertions, 6 deletions
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index ee68b69..7bc0b55 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -2216,12 +2216,18 @@ Order_eval::statement(Block* block, size_t* pindex, Statement* s)
Expression::traverse(&init, &find_eval_ordering);
}
- if (find_eval_ordering.size() <= 1)
- {
- // If there is only one expression with a side-effect, we can
- // leave it in place.
- return TRAVERSE_CONTINUE;
- }
+ size_t c = find_eval_ordering.size();
+ if (c == 0)
+ return TRAVERSE_CONTINUE;
+
+ // If there is only one expression with a side-effect, we can
+ // usually leave it in place. However, for an assignment statement,
+ // we need to evaluate an expression on the right hand side before
+ // we evaluate any index expression on the left hand side, so for
+ // that case we always move the expression. Otherwise we mishandle
+ // m[0] = len(m) where m is a map.
+ if (c == 1 && s->classification() != Statement::STATEMENT_ASSIGNMENT)
+ return TRAVERSE_CONTINUE;
bool is_thunk = s->thunk_statement() != NULL;
for (Find_eval_ordering::const_iterator p = find_eval_ordering.begin();