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:
parent
2fda8e144a
commit
4063e61bc6
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 ())
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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" } */
|
||||
|
|
Loading…
Reference in New Issue