re PR c++/53356 (ICE in verify_gimple_stmt, at tree-cfg.c:4258)

PR c++/53356
	* tree.c (stabilize_init): Handle stabilizing a TARGET_EXPR
	representing a bitwise copy of a glvalue.

From-SVN: r188029
This commit is contained in:
Jason Merrill 2012-05-30 18:07:23 -04:00 committed by Jason Merrill
parent 989e6706f1
commit 66edf32a6f
5 changed files with 63 additions and 17 deletions

View File

@ -1,5 +1,9 @@
2012-05-30 Jason Merrill <jason@redhat.com>
PR c++/53356
* tree.c (stabilize_init): Handle stabilizing a TARGET_EXPR
representing a bitwise copy of a glvalue.
* tree.c (stabilize_expr): Tweak logic.
PR c++/53356

View File

@ -3389,7 +3389,7 @@ stabilize_aggr_init (tree call, tree *initp)
takes care not to introduce additional temporaries.
Returns TRUE iff the expression was successfully pre-evaluated,
i.e., if INIT is now side-effect free, except for, possible, a
i.e., if INIT is now side-effect free, except for, possibly, a
single call to a constructor. */
bool
@ -3402,21 +3402,37 @@ stabilize_init (tree init, tree *initp)
if (t == error_mark_node || processing_template_decl)
return true;
if (TREE_CODE (t) == INIT_EXPR
&& TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR
&& TREE_CODE (TREE_OPERAND (t, 1)) != CONSTRUCTOR
&& TREE_CODE (TREE_OPERAND (t, 1)) != AGGR_INIT_EXPR)
{
TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
return true;
}
if (TREE_CODE (t) == INIT_EXPR)
t = TREE_OPERAND (t, 1);
if (TREE_CODE (t) == TARGET_EXPR)
t = TARGET_EXPR_INITIAL (t);
if (TREE_CODE (t) == COMPOUND_EXPR)
t = expr_last (t);
/* If the RHS can be stabilized without breaking copy elision, stabilize
it. We specifically don't stabilize class prvalues here because that
would mean an extra copy, but they might be stabilized below. */
if (TREE_CODE (init) == INIT_EXPR
&& TREE_CODE (t) != CONSTRUCTOR
&& TREE_CODE (t) != AGGR_INIT_EXPR
&& (SCALAR_TYPE_P (TREE_TYPE (t))
|| lvalue_or_rvalue_with_address_p (t)))
{
TREE_OPERAND (init, 1) = stabilize_expr (t, initp);
return true;
}
if (TREE_CODE (t) == COMPOUND_EXPR
&& TREE_CODE (init) == INIT_EXPR)
{
tree last = expr_last (t);
/* Handle stabilizing the EMPTY_CLASS_EXPR pattern. */
if (!TREE_SIDE_EFFECTS (last))
{
*initp = t;
TREE_OPERAND (init, 1) = last;
return true;
}
}
if (TREE_CODE (t) == CONSTRUCTOR)
{
/* Aggregate initialization: stabilize each of the field
@ -3439,11 +3455,6 @@ stabilize_init (tree init, tree *initp)
return good;
}
/* If the initializer is a COND_EXPR, we can't preevaluate
anything. */
if (TREE_CODE (t) == COND_EXPR)
return false;
if (TREE_CODE (t) == CALL_EXPR)
{
stabilize_call (t, initp);

View File

@ -1,3 +1,9 @@
2012-05-30 Jason Merrill <jason@redhat.com>
PR c++/53356
* g++.dg/init/new34.C: New.
* g++.dg/tree-ssa/stabilize1.C: New.
2012-05-30 Jakub Jelinek <jakub@redhat.com>
PR c++/53356

View File

@ -0,0 +1,11 @@
// PR c++/53356
struct A { A(); ~A(); };
struct B {
operator const A () const;
};
A* cause_ICE() {
return new A((A(),A()));
}

View File

@ -0,0 +1,14 @@
// PR c++/53356
// { dg-options "-fdump-tree-gimple" }
// { dg-final { scan-tree-dump-not "= 0" "gimple" } }
// { dg-final { cleanup-tree-dump "gimple" } }
class A {};
struct B {
operator const A &() const;
};
A* cause_ICE() {
return new A(B());
}