except.c (expand_fixup_region_end): New fn.
* except.c (expand_fixup_region_end): New fn. (expand_fixup_region_start): Likewise. (expand_eh_region_start_tree): Store cleanup into finalization here. * stmt.c (expand_cleanups): Use them to protect fixups. From-SVN: r16929
This commit is contained in:
parent
aa36c0813a
commit
9762d48da5
3 changed files with 66 additions and 0 deletions
|
@ -1,3 +1,10 @@
|
|||
Wed Dec 3 12:01:56 1997 Jason Merrill <jason@yorick.cygnus.com>
|
||||
|
||||
* except.c (expand_fixup_region_end): New fn.
|
||||
(expand_fixup_region_start): Likewise.
|
||||
(expand_eh_region_start_tree): Store cleanup into finalization here.
|
||||
* stmt.c (expand_cleanups): Use them to protect fixups.
|
||||
|
||||
Wed Dec 3 11:41:13 1997 Gavin Koch <gavin@cygnus.com>
|
||||
|
||||
* mips/mips.md (muldi3_r4000): Broaden the output template
|
||||
|
|
52
gcc/except.c
52
gcc/except.c
|
@ -1013,6 +1013,7 @@ expand_eh_region_start_tree (decl, cleanup)
|
|||
}
|
||||
|
||||
expand_eh_region_start_for_decl (decl);
|
||||
ehstack.top->entry->finalization = cleanup;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1138,6 +1139,57 @@ expand_eh_region_end (handler)
|
|||
}
|
||||
}
|
||||
|
||||
/* End the EH region for a goto fixup. We only need them in the region-based
|
||||
EH scheme. */
|
||||
|
||||
void
|
||||
expand_fixup_region_start ()
|
||||
{
|
||||
if (! doing_eh (0) || exceptions_via_longjmp)
|
||||
return;
|
||||
|
||||
expand_eh_region_start ();
|
||||
}
|
||||
|
||||
/* End the EH region for a goto fixup. CLEANUP is the cleanup we just
|
||||
expanded; to avoid running it twice if it throws, we look through the
|
||||
ehqueue for a matching region and rethrow from its outer_context. */
|
||||
|
||||
void
|
||||
expand_fixup_region_end (cleanup)
|
||||
tree cleanup;
|
||||
{
|
||||
tree t;
|
||||
struct eh_node *node;
|
||||
int yes;
|
||||
|
||||
if (! doing_eh (0) || exceptions_via_longjmp)
|
||||
return;
|
||||
|
||||
for (node = ehstack.top; node && node->entry->finalization != cleanup; )
|
||||
node = node->chain;
|
||||
if (node == 0)
|
||||
for (node = ehqueue.head; node && node->entry->finalization != cleanup; )
|
||||
node = node->chain;
|
||||
if (node == 0)
|
||||
abort ();
|
||||
|
||||
yes = suspend_momentary ();
|
||||
|
||||
t = build (RTL_EXPR, void_type_node, NULL_RTX, const0_rtx);
|
||||
TREE_SIDE_EFFECTS (t) = 1;
|
||||
do_pending_stack_adjust ();
|
||||
start_sequence_for_rtl_expr (t);
|
||||
expand_internal_throw (node->entry->outer_context);
|
||||
do_pending_stack_adjust ();
|
||||
RTL_EXPR_SEQUENCE (t) = get_insns ();
|
||||
end_sequence ();
|
||||
|
||||
resume_momentary (yes);
|
||||
|
||||
expand_eh_region_end (t);
|
||||
}
|
||||
|
||||
/* If we are using the setjmp/longjmp EH codegen method, we emit a
|
||||
call to __sjthrow.
|
||||
|
||||
|
|
|
@ -4229,7 +4229,14 @@ expand_cleanups (list, dont_do, in_fixup, reachable)
|
|||
the target. Though the cleanups are expanded multiple
|
||||
times, the control paths are non-overlapping so the
|
||||
cleanups will not be executed twice. */
|
||||
|
||||
/* We may need to protect fixups with rethrow regions. */
|
||||
int protect = (in_fixup && ! TREE_ADDRESSABLE (tail));
|
||||
if (protect)
|
||||
expand_fixup_region_start ();
|
||||
expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
|
||||
if (protect)
|
||||
expand_fixup_region_end (TREE_VALUE (tail));
|
||||
free_temp_slots ();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue