summaryrefslogtreecommitdiff
path: root/gcc/stmt.c
diff options
context:
space:
mode:
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>1996-05-17 21:48:14 +0000
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>1996-05-17 21:48:14 +0000
commit836b95039244904504667e1b886662c54546b561 (patch)
treed45ed9209ff2030610011f8365b79f5db25beac6 /gcc/stmt.c
parent981a7aca054114de335902b83fedd183c5e7f6c6 (diff)
downloadgcc-836b95039244904504667e1b886662c54546b561.tar.gz
* expr.c (expand_expr, cond TARGET_EXPR): Make TARGET_EXPRs
redoable for UNSAVE_EXPR. * stmt.c (expand_decl_cleanup): Wrap the cleanup in an UNSAVE_EXPR to that we can redo it. * tree.c (unsave_expr_now): Handle TARGET_EXPRs fully now. * tree.def (TARGET_EXPR): Add a third field so that TARGET_EXPRs are redoable. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@12018 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/stmt.c')
-rw-r--r--gcc/stmt.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 6a2e670d95e..d9551f6a8ac 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -3687,12 +3687,9 @@ bc_expand_decl_init (decl)
/* 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. */
@@ -3711,6 +3708,8 @@ expand_decl_cleanup (decl, cleanup)
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. */