mirror of git://gcc.gnu.org/git/gcc.git
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>
|
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.c (cgraph_add_to_same_comdat_group): New.
|
||||||
* cgraph.h: Declare it.
|
* cgraph.h: Declare it.
|
||||||
* ipa.c (function_and_variable_visibility): Make sure thunks
|
* ipa.c (function_and_variable_visibility): Make sure thunks
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
2011-07-08 Jason Merrill <jason@redhat.com>
|
2011-07-08 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
PR c++/45437
|
||||||
|
* c-omp.c (check_omp_for_incr_expr): Handle preevaluation.
|
||||||
|
|
||||||
PR c++/49673
|
PR c++/49673
|
||||||
* c-common.c (c_apply_type_quals_to_decl): Don't check
|
* c-common.c (c_apply_type_quals_to_decl): Don't check
|
||||||
TYPE_NEEDS_CONSTRUCTING.
|
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,
|
return fold_build2_loc (loc, PLUS_EXPR,
|
||||||
TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
|
TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
2011-07-08 Jason Merrill <jason@redhat.com>
|
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.
|
* method.c (use_thunk): Use cgraph_add_to_same_comdat_group.
|
||||||
* optimize.c (maybe_clone_body): Likewise.
|
* optimize.c (maybe_clone_body): Likewise.
|
||||||
* semantics.c (maybe_add_lambda_conv_op): 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
|
else
|
||||||
{
|
{
|
||||||
|
tree init = NULL_TREE;
|
||||||
|
|
||||||
/* A binary op has been requested. Combine the old LHS
|
/* A binary op has been requested. Combine the old LHS
|
||||||
value with the RHS producing the value we should actually
|
value with the RHS producing the value we should actually
|
||||||
store into the LHS. */
|
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 (TREE_TYPE (lhstype)))
|
||||||
|| MAYBE_CLASS_TYPE_P (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);
|
lhs = stabilize_reference (lhs);
|
||||||
|
rhs = stabilize_expr (rhs, &init);
|
||||||
newrhs = cp_build_binary_op (input_location,
|
newrhs = cp_build_binary_op (input_location,
|
||||||
modifycode, lhs, rhs,
|
modifycode, lhs, rhs,
|
||||||
complain);
|
complain);
|
||||||
|
|
@ -6682,6 +6694,9 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (init)
|
||||||
|
newrhs = build2 (COMPOUND_EXPR, TREE_TYPE (newrhs), init, newrhs);
|
||||||
|
|
||||||
/* Now it looks like a plain assignment. */
|
/* Now it looks like a plain assignment. */
|
||||||
modifycode = NOP_EXPR;
|
modifycode = NOP_EXPR;
|
||||||
if (c_dialect_objc ())
|
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,
|
saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
|
||||||
lhs_addr, lhs_var);
|
lhs_addr, lhs_var);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
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>
|
2011-07-08 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR target/49621
|
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" } */
|
(a = a++) && b; /* { dg-warning "undefined" "sequence point warning" } */
|
||||||
b, (a = a++); /* { 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 = 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; /* { dg-bogus "undefined" "bogus sequence point warning" } */
|
||||||
a = (a++ && 4); /* { dg-bogus "undefined" "bogus sequence point warning" } */
|
a = (a++ && 4); /* { dg-bogus "undefined" "bogus sequence point warning" } */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue