re PR c++/45437 (Loses reference during update)

PR c++/45437
gcc/
	* gimplify.c (goa_stabilize_expr): Handle RHS preevaluation in
	compound assignment.
gcc/c-family/
	* c-omp.c (check_omp_for_incr_expr): Handle preevaluation.
gcc/cp/
	* typeck.c (cp_build_modify_expr): Preevaluate RHS.

From-SVN: r176072
This commit is contained in:
Jason Merrill 2011-07-08 23:33:54 -04:00 committed by Jason Merrill
parent 2fda8e144a
commit 4063e61bc6
9 changed files with 75 additions and 1 deletions

View File

@ -1,5 +1,9 @@
2011-07-08 Jason Merrill <jason@redhat.com>
PR c++/45437
* gimplify.c (goa_stabilize_expr): Handle RHS preevaluation in
compound assignment.
* cgraph.c (cgraph_add_to_same_comdat_group): New.
* cgraph.h: Declare it.
* ipa.c (function_and_variable_visibility): Make sure thunks

View File

@ -1,5 +1,8 @@
2011-07-08 Jason Merrill <jason@redhat.com>
PR c++/45437
* c-omp.c (check_omp_for_incr_expr): Handle preevaluation.
PR c++/49673
* c-common.c (c_apply_type_quals_to_decl): Don't check
TYPE_NEEDS_CONSTRUCTING.

View File

@ -213,6 +213,27 @@ check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
return fold_build2_loc (loc, PLUS_EXPR,
TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
break;
case COMPOUND_EXPR:
{
/* cp_build_modify_expr forces preevaluation of the RHS to make
sure that it is evaluated before the lvalue-rvalue conversion
is applied to the LHS. Reconstruct the original expression. */
tree op0 = TREE_OPERAND (exp, 0);
if (TREE_CODE (op0) == TARGET_EXPR
&& !VOID_TYPE_P (TREE_TYPE (op0)))
{
tree op1 = TREE_OPERAND (exp, 1);
tree temp = TARGET_EXPR_SLOT (op0);
if (TREE_CODE_CLASS (TREE_CODE (op1)) == tcc_binary
&& TREE_OPERAND (op1, 1) == temp)
{
op1 = copy_node (op1);
TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
return check_omp_for_incr_expr (loc, op1, decl);
}
}
break;
}
default:
break;
}

View File

@ -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.

View File

@ -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 ())

View File

@ -6451,6 +6451,13 @@ goa_stabilize_expr (tree *expr_p, gimple_seq *pre_p, tree lhs_addr,
saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
lhs_addr, lhs_var);
break;
case COMPOUND_EXPR:
/* Break out any preevaluations from cp_build_modify_expr. */
for (; TREE_CODE (expr) == COMPOUND_EXPR;
expr = TREE_OPERAND (expr, 1))
gimplify_stmt (&TREE_OPERAND (expr, 0), pre_p);
*expr_p = expr;
return goa_stabilize_expr (expr_p, pre_p, lhs_addr, lhs_var);
default:
break;
}

View File

@ -1,3 +1,9 @@
2011-07-08 Jason Merrill <jason@redhat.com>
PR c++/45437
* g++.dg/expr/compound-asn1.C: New.
* g++.dg/warn/sequence-pt-1.C: Change one dg-error to dg-bogus.
2011-07-08 Jakub Jelinek <jakub@redhat.com>
PR target/49621

View File

@ -0,0 +1,15 @@
// PR c++/45437
// { dg-options -Wsequence-point }
// { dg-do run }
bool f(bool& b) {
b = true;
return false;
}
int main() {
bool b = false;
b |= f(b);
if (!b)
return 1;
}

View File

@ -62,7 +62,7 @@ foo (int a, int b, int n, int p, int *ptr, struct s *sptr,
(a = a++) && b; /* { dg-warning "undefined" "sequence point warning" } */
b, (a = a++); /* { dg-warning "undefined" "sequence point warning" } */
(a = a++), b; /* { dg-warning "undefined" "sequence point warning" } */
a ^= b ^= a ^= b; /* { dg-warning "undefined" "sequence point warning" } */
a ^= b ^= a ^= b; /* { dg-bogus "undefined" "sequence point warning" } */
a = a; /* { dg-bogus "undefined" "bogus sequence point warning" } */
a = (a++ && 4); /* { dg-bogus "undefined" "bogus sequence point warning" } */