This patch to the Go frontend loads LHS subexpressions of op= assignment only once. This avoids inconsistencies if the variables are changed by evaluating the RHS. This fixes https://go.dev/issue/52811. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline. There is a test case in the main Go repo that will be copied over at some point.
Ian
88c35c4d23e2458687508187601f8d2b8570bbe3 diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index daa725f9de9..5fa8becde3e 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -f5bc28a30b7503015bbef38afb5812313184e822 +9d07072e58ca4f9f05343dfd3475b9f49dae5ec5 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 95fa3c48709..b3db843365e 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -1260,6 +1260,16 @@ Assignment_operation_statement::do_lower(Gogo*, Named_object*, Move_ordered_evals moe(b); this->lhs_->traverse_subexpressions(&moe); + // We can still be left with subexpressions that have to be loaded + // even if they don't have side effects themselves, in case the RHS + // changes variables named on the LHS. + int i; + if (this->lhs_->must_eval_subexpressions_in_order(&i)) + { + Move_subexpressions ms(i, b); + this->lhs_->traverse_subexpressions(&ms); + } + Expression* lval = this->lhs_->copy(); Operator op;