summaryrefslogtreecommitdiff
path: root/gcc/stmt.c
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1995-01-20 19:27:33 +0000
committerMike Stump <mrs@gcc.gnu.org>1995-01-20 19:27:33 +0000
commit50d1b7a1166c5208498a8884229c8c3a08e3eb05 (patch)
tree462c72b7e6dc0c53d6033df90062f2db9a7ee1bc /gcc/stmt.c
parent28ed46164618631d07f5ddee9a9743c378d6cbcc (diff)
downloadgcc-50d1b7a1166c5208498a8884229c8c3a08e3eb05.tar.gz
stmt.c (expand_cleanups): Add 4th argument to indicate if code needs to be expanded for the cleanup.
* stmt.c (expand_cleanups): Add 4th argument to indicate if code needs to be expanded for the cleanup. (expand_goto_internal): Ditto. (bc_expand_goto_internal): Ditto. (fixup_gotos): Ditto. (expand_end_bindings): Ditto. We now always call expand_cleanups, even after BARRIERs, so that the call to the exception handling routines is always done. From-SVN: r8776
Diffstat (limited to 'gcc/stmt.c')
-rw-r--r--gcc/stmt.c87
1 files changed, 47 insertions, 40 deletions
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 30eb838b717..4d850e75686 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -449,7 +449,7 @@ static void bc_expand_variable_local_init PROTO((tree));
static void bc_expand_decl_init PROTO((tree));
static void expand_null_return_1 PROTO((rtx, int));
static int tail_recursion_args PROTO((tree, tree));
-static void expand_cleanups PROTO((tree, tree, int));
+static void expand_cleanups PROTO((tree, tree, int, int));
static void bc_expand_start_case PROTO((struct nesting *, tree,
tree, char *));
static int bc_pushcase PROTO((tree, tree));
@@ -804,7 +804,7 @@ expand_goto_internal (body, label, last_insn)
/* Execute the cleanups for blocks we are exiting. */
if (block->data.block.cleanups != 0)
{
- expand_cleanups (block->data.block.cleanups, NULL_TREE, 1);
+ expand_cleanups (block->data.block.cleanups, NULL_TREE, 1, 1);
do_pending_stack_adjust ();
}
}
@@ -868,7 +868,7 @@ bc_expand_goto_internal (opcode, label, body)
/* Execute the cleanups for blocks we are exiting. */
if (block->data.block.cleanups != 0)
{
- expand_cleanups (block->data.block.cleanups, NULL_TREE, 1);
+ expand_cleanups (block->data.block.cleanups, NULL_TREE, 1, 1);
do_pending_stack_adjust ();
}
}
@@ -1181,7 +1181,7 @@ fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
if (TREE_ADDRESSABLE (lists)
&& TREE_VALUE (lists) != 0)
{
- expand_cleanups (TREE_VALUE (lists), NULL_TREE, 1);
+ expand_cleanups (TREE_VALUE (lists), NULL_TREE, 1, 1);
/* Pop any pushes done in the cleanups,
in case function is about to return. */
do_pending_stack_adjust ();
@@ -3093,32 +3093,32 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
|| thisblock->data.block.cleanups != 0)
{
/* Only clean up here if this point can actually be reached. */
- if (GET_CODE (get_last_insn ()) != BARRIER)
- {
- /* Don't let cleanups affect ({...}) constructs. */
- int old_expr_stmts_for_value = expr_stmts_for_value;
- rtx old_last_expr_value = last_expr_value;
- tree old_last_expr_type = last_expr_type;
- expr_stmts_for_value = 0;
-
- /* Do the cleanups. */
- expand_cleanups (thisblock->data.block.cleanups, NULL_TREE, 0);
- do_pending_stack_adjust ();
+ int reachable = GET_CODE (get_last_insn ()) != BARRIER;
+
+ /* Don't let cleanups affect ({...}) constructs. */
+ int old_expr_stmts_for_value = expr_stmts_for_value;
+ rtx old_last_expr_value = last_expr_value;
+ tree old_last_expr_type = last_expr_type;
+ expr_stmts_for_value = 0;
- expr_stmts_for_value = old_expr_stmts_for_value;
- last_expr_value = old_last_expr_value;
- last_expr_type = old_last_expr_type;
+ /* Do the cleanups. */
+ expand_cleanups (thisblock->data.block.cleanups, NULL_TREE, 0, reachable);
+ if (reachable)
+ do_pending_stack_adjust ();
- /* Restore the stack level. */
+ expr_stmts_for_value = old_expr_stmts_for_value;
+ last_expr_value = old_last_expr_value;
+ last_expr_type = old_last_expr_type;
- if (thisblock->data.block.stack_level != 0)
- {
- emit_stack_restore (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
- thisblock->data.block.stack_level, NULL_RTX);
- if (nonlocal_goto_handler_slot != 0)
- emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level,
- NULL_RTX);
- }
+ /* Restore the stack level. */
+
+ if (reachable && thisblock->data.block.stack_level != 0)
+ {
+ emit_stack_restore (thisblock->next ? SAVE_BLOCK : SAVE_FUNCTION,
+ thisblock->data.block.stack_level, NULL_RTX);
+ if (nonlocal_goto_handler_slot != 0)
+ emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level,
+ NULL_RTX);
}
/* Any gotos out of this block must also do these things.
@@ -3684,35 +3684,42 @@ expand_anon_union_decl (decl, cleanup, decl_elts)
a value that is being returned out of the scope.
If IN_FIXUP is non-zero, we are generating this cleanup for a fixup
- goto and handle protection regions specially in that case. */
+ goto and handle protection regions specially in that case.
+
+ If REACHABLE, we emit code, otherwise just inform the exception handling
+ code about this finalization. */
static void
-expand_cleanups (list, dont_do, in_fixup)
+expand_cleanups (list, dont_do, in_fixup, reachable)
tree list;
tree dont_do;
int in_fixup;
+ int reachable;
{
tree tail;
for (tail = list; tail; tail = TREE_CHAIN (tail))
if (dont_do == 0 || TREE_PURPOSE (tail) != dont_do)
{
if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
- expand_cleanups (TREE_VALUE (tail), dont_do, in_fixup);
+ expand_cleanups (TREE_VALUE (tail), dont_do, in_fixup, reachable);
else
{
if (! in_fixup)
(*interim_eh_hook) (TREE_VALUE (tail));
- /* Cleanups may be run multiple times. For example,
- when exiting a binding contour, we expand the
- cleanups associated with that contour. When a goto
- within that binding contour has a target outside that
- contour, it will expand all cleanups from its scope to
- the target. Though the cleanups are expanded multiple
- times, the control paths are non-overlapping so the
- cleanups will not be executed twice. */
- expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
- free_temp_slots ();
+ if (reachable)
+ {
+ /* Cleanups may be run multiple times. For example,
+ when exiting a binding contour, we expand the
+ cleanups associated with that contour. When a goto
+ within that binding contour has a target outside that
+ contour, it will expand all cleanups from its scope to
+ the target. Though the cleanups are expanded multiple
+ times, the control paths are non-overlapping so the
+ cleanups will not be executed twice. */
+ expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
+ free_temp_slots ();
+ }
}
}
}