diff options
author | Jason Merrill <jason@yorick.cygnus.com> | 1997-12-03 20:04:31 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 1997-12-03 15:04:31 -0500 |
commit | 9762d48da5d567c89e920a51149a2c9aef960150 (patch) | |
tree | 2a7cbc8dffb4904b9ccaed9c7d077f4874fcddcb | |
parent | aa36c0813a2f8c213bb5b041ce67e7032b078c5a (diff) | |
download | gcc-9762d48da5d567c89e920a51149a2c9aef960150.zip gcc-9762d48da5d567c89e920a51149a2c9aef960150.tar.gz gcc-9762d48da5d567c89e920a51149a2c9aef960150.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/except.c | 52 | ||||
-rw-r--r-- | gcc/stmt.c | 7 |
3 files changed, 66 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f9f324..2af7dc1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/except.c b/gcc/except.c index 0b5ceec..a493375 100644 --- a/gcc/except.c +++ b/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 (); } } |