aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@yorick.cygnus.com>1997-12-03 20:04:31 +0000
committerJason Merrill <jason@gcc.gnu.org>1997-12-03 15:04:31 -0500
commit9762d48da5d567c89e920a51149a2c9aef960150 (patch)
tree2a7cbc8dffb4904b9ccaed9c7d077f4874fcddcb
parentaa36c0813a2f8c213bb5b041ce67e7032b078c5a (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/except.c52
-rw-r--r--gcc/stmt.c7
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.
diff --git a/gcc/stmt.c b/gcc/stmt.c
index d61de3a..ee9139c 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -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 ();
}
}