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:
parent
8218f92fdf
commit
9beafc83ca
4 changed files with 72 additions and 39 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
10
gcc/testsuite/g++.dg/eh/cast1.C
Normal file
10
gcc/testsuite/g++.dg/eh/cast1.C
Normal file
|
@ -0,0 +1,10 @@
|
|||
// PR c++/28523
|
||||
|
||||
class A {};
|
||||
class B : public A {};
|
||||
|
||||
int main()
|
||||
{
|
||||
throw (A) B();
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue