DECL_RTL (slot) = target;
}
- exp1 = TREE_OPERAND (exp, 1);
+ exp1 = TREE_OPERAND (exp, 3) = TREE_OPERAND (exp, 1);
/* Mark it as expanded. */
TREE_OPERAND (exp, 1) = NULL_TREE;
/* CLEANUP is an expression to be executed at exit from this binding contour;
for example, in C++, it might call the destructor for this variable.
- If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them
- either before or after calling `expand_decl_cleanup' but before compiling
- any subsequent expressions. This is because CLEANUP may be expanded
- more than once, on different branches of execution.
- For the same reason, CLEANUP may not contain a CALL_EXPR
- except as its topmost node--else `preexpand_calls' would get confused.
+ We wrap CLEANUP in an UNSAVE_EXPR node, so that we can expand the
+ CLEANUP multiple times, and have the correct semantics. This
+ happens in exception handling, and for non-local gotos.
If CLEANUP is nonzero and DECL is zero, we record a cleanup
that is not associated with any particular variable. */
if (cleanup != 0)
{
+ cleanup = unsave_expr (cleanup);
+
thisblock->data.block.cleanups
= temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);
/* If this block has a cleanup, it belongs in stack_block_stack. */
break;
case TARGET_EXPR:
- sorry ("TARGET_EXPR reused inside UNSAVE_EXPR");
+ TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 3);
+ TREE_OPERAND (expr, 3) = NULL_TREE;
break;
case RTL_EXPR:
- warning ("RTL_EXPR reused inside UNSAVE_EXPR");
- RTL_EXPR_SEQUENCE (expr) = NULL_RTX;
+ /* I don't yet know how to emit a sequence multiple times. */
+ if (RTL_EXPR_SEQUENCE (expr) != NULL_RTX)
+ abort ();
break;
case CALL_EXPR:
/* For TARGET_EXPR, operand 0 is the target of an initialization,
operand 1 is the initializer for the target,
- and operand 2 is the cleanup for this node, if any. */
+ and operand 2 is the cleanup for this node, if any.
+ and operand 3 is the saved initializer after this node has been
+ expanded once, this is so we can re-expand the tree later. */
DEFTREECODE (TARGET_EXPR, "target_expr", "e", 3)
/* Conditional expression ( ... ? ... : ... in C).