This patch to the Go frontend fixes the order of evaluation for a
statement like m[0] = len(m) when m is a map. I added a test case for
this to the master testsuite. Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu. Committed to mainline and 4.7 branch.
Ian
diff -r 5b5853844f00 go/gogo.cc
--- a/go/gogo.cc Tue Apr 24 07:52:37 2012 -0700
+++ b/go/gogo.cc Tue Apr 24 09:22:09 2012 -0700
@@ -2216,12 +2216,18 @@
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();