re PR c++/28523 (Throw of a derived class casted to its base class using a C-style cast)

PR c++/28523
	* tree.c (stabilize_expr): Tweak documentation.  Add assertion.
	(stabilize_call): Tweak documentation.
	(stabilize_init): Only call stabilize_call for calls.
	PR c++/28523
	* g++.dg/eh/cast1.C: New test.

From-SVN: r115862
This commit is contained in:
Mark Mitchell 2006-08-01 20:04:57 +00:00 committed by Mark Mitchell
parent 8218f92fdf
commit 9beafc83ca
4 changed files with 72 additions and 39 deletions

View file

@ -1,3 +1,10 @@
2006-07-31 Mark Mitchell <mark@codesourcery.com>
PR c++/28523
* tree.c (stabilize_expr): Tweak documentation. Add assertion.
(stabilize_call): Tweak documentation.
(stabilize_init): Only call stabilize_call for calls.
2006-08-01 Steve Ellcey <sje@cup.hp.com>
PR c++/28432

View file

@ -2229,9 +2229,11 @@ decl_linkage (tree decl)
return lk_internal;
}
/* EXP is an expression that we want to pre-evaluate. Returns via INITP an
expression to perform the pre-evaluation, and returns directly an
expression to use the precalculated result. */
/* EXP is an expression that we want to pre-evaluate. Returns (in
*INITP) an expression that will perform the pre-evaluation. The
value returned by this function is a side-effect free expression
equivalent to the pre-evaluated expression. Callers must ensure
that *INITP is evaluated before EXP. */
tree
stabilize_expr (tree exp, tree* initp)
@ -2239,9 +2241,7 @@ stabilize_expr (tree exp, tree* initp)
tree init_expr;
if (!TREE_SIDE_EFFECTS (exp))
{
init_expr = NULL_TREE;
}
init_expr = NULL_TREE;
else if (!real_lvalue_p (exp)
|| !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (exp)))
{
@ -2255,8 +2255,9 @@ stabilize_expr (tree exp, tree* initp)
exp = TARGET_EXPR_SLOT (init_expr);
exp = build_indirect_ref (exp, 0);
}
*initp = init_expr;
gcc_assert (!TREE_SIDE_EFFECTS (exp));
return exp;
}
@ -2273,8 +2274,10 @@ add_stmt_to_compound (tree orig, tree new)
return build2 (COMPOUND_EXPR, void_type_node, orig, new);
}
/* Like stabilize_expr, but for a call whose args we want to
pre-evaluate. */
/* Like stabilize_expr, but for a call whose arguments we want to
pre-evaluate. CALL is modified in place to use the pre-evaluated
arguments, while, upon return, *INITP contains an expression to
compute the arguments. */
void
stabilize_call (tree call, tree *initp)
@ -2299,50 +2302,58 @@ stabilize_call (tree call, tree *initp)
*initp = inits;
}
/* Like stabilize_expr, but for an initialization. If we are initializing
an object of class type, we don't want to introduce an extra temporary,
so we look past the TARGET_EXPR and stabilize the arguments of the call
instead. */
/* Like stabilize_expr, but for an initialization.
If the initialization is for an object of class type, this function
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
single call to a constructor. */
bool
stabilize_init (tree init, tree *initp)
{
tree t = init;
*initp = NULL_TREE;
if (t == error_mark_node)
return true;
if (TREE_CODE (t) == INIT_EXPR
&& TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR)
TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
else
{
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 (TREE_CODE (t) == CONSTRUCTOR
&& EMPTY_CONSTRUCTOR_P (t))
{
/* Default-initialization. */
*initp = NULL_TREE;
return true;
}
/* If the initializer is a COND_EXPR, we can't preevaluate
anything. */
if (TREE_CODE (t) == COND_EXPR)
return false;
/* The TARGET_EXPR might be initializing via bitwise copy from
another variable; leave that alone. */
if (TREE_SIDE_EFFECTS (t))
stabilize_call (t, initp);
TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
return true;
}
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 (TREE_CODE (t) == CONSTRUCTOR
&& EMPTY_CONSTRUCTOR_P (t))
/* Default-initialization. */
return true;
/* 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
|| TREE_CODE (t) == AGGR_INIT_EXPR)
{
stabilize_call (t, initp);
return true;
}
/* The initialization is being performed via a bitwise copy -- and
the item copied may have side effects. */
return TREE_SIDE_EFFECTS (init);
}
/* Like "fold", but should be used whenever we might be processing the

View file

@ -1,3 +1,8 @@
2006-07-31 Mark Mitchell <mark@codesourcery.com>
PR c++/28523
* g++.dg/eh/cast1.C: New test.
2006-08-01 Thomas Koenig <Thomas.Koenig@online.de>
PR libfortran/28452

View file

@ -0,0 +1,10 @@
// PR c++/28523
class A {};
class B : public A {};
int main()
{
throw (A) B();
return 0;
}