diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 15 |
2 files changed, 18 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3f776b0..cbdc4d8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2011-07-08 Jason Merrill <jason@redhat.com> + PR c++/45437 + * typeck.c (cp_build_modify_expr): Preevaluate RHS. + * method.c (use_thunk): Use cgraph_add_to_same_comdat_group. * optimize.c (maybe_clone_body): Likewise. * semantics.c (maybe_add_lambda_conv_op): Likewise. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 5febff5..d87c107 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6663,6 +6663,8 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, } else { + tree init = NULL_TREE; + /* A binary op has been requested. Combine the old LHS value with the RHS producing the value we should actually store into the LHS. */ @@ -6670,7 +6672,17 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, && MAYBE_CLASS_TYPE_P (TREE_TYPE (lhstype))) || MAYBE_CLASS_TYPE_P (lhstype))); + /* Preevaluate the RHS to make sure its evaluation is complete + before the lvalue-to-rvalue conversion of the LHS: + + [expr.ass] With respect to an indeterminately-sequenced + function call, the operation of a compound assignment is a + single evaluation. [ Note: Therefore, a function call shall + not intervene between the lvalue-to-rvalue conversion and the + side effect associated with any single compound assignment + operator. -- end note ] */ lhs = stabilize_reference (lhs); + rhs = stabilize_expr (rhs, &init); newrhs = cp_build_binary_op (input_location, modifycode, lhs, rhs, complain); @@ -6682,6 +6694,9 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, return error_mark_node; } + if (init) + newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs); + /* Now it looks like a plain assignment. */ modifycode = NOP_EXPR; if (c_dialect_objc ()) |