aboutsummaryrefslogtreecommitdiff
path: root/gcc/except.c
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@cygnus.com>1998-09-15 11:20:52 +0000
committerAndrew Macleod <amacleod@gcc.gnu.org>1998-09-15 11:20:52 +0000
commitbf71cd2eaa2d7091cd02f429beeec279b6a5c52d (patch)
tree6b24980704695c7ec0f059391cfe4c686deb5c76 /gcc/except.c
parent8a21007c9409ad2be041c05c304295ff449538b7 (diff)
downloadgcc-bf71cd2eaa2d7091cd02f429beeec279b6a5c52d.zip
gcc-bf71cd2eaa2d7091cd02f429beeec279b6a5c52d.tar.gz
gcc-bf71cd2eaa2d7091cd02f429beeec279b6a5c52d.tar.bz2
[multiple changes]
Tue Sep 15 14:10:54 EDT 1998 Andrew MacLeod <amacleod@cygnus.com> * except.h (struct eh_entry): Add false_label field. (end_catch_handler): Add prototype. * except.c (push_eh_entry): Set false_label field to NULL_RTX. (start_catch_handler): When using old style exceptions, issue runtime typematch code before continuing with the handler. (end_catch_handler): New function, generates label after handler if needed by older style exceptions. (expand_start_all_catch): No need to check for new style exceptions. (output_exception_table_entry): Only output the first handler label for old style exceptions. * libgcc2.c (__eh_rtime_match): New routine to lump runtime matching mechanism into one function, if a runtime matcher is provided. 1998-09-15 Andrew MacLeod <amacleod@cygnus.com> * cp/except.c (expand_start_catch_block): No need to check for new exception model. (process_start_catch_block_old): Deleted. (process_start_catch_block): Add call to start_decl_1(). (expand_end_catch_block): Add call to end_catch_handler(). * cp/exception.cc (__cplus_type_matcher): Only check the exception language if there is an exception table. From-SVN: r22425
Diffstat (limited to 'gcc/except.c')
-rw-r--r--gcc/except.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/gcc/except.c b/gcc/except.c
index 5f2c61a..f0d0009 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -597,6 +597,7 @@ push_eh_entry (stack)
entry->finalization = NULL_TREE;
entry->label_used = 0;
entry->exception_handler_label = gen_exception_label ();
+ entry->false_label = NULL_RTX;
node->entry = entry;
node->chain = stack->top;
@@ -1600,6 +1601,54 @@ start_catch_handler (rtime)
receive_exception_label (handler_label);
add_new_handler (eh_region_entry, get_new_handler (handler_label, rtime));
+
+ if (flag_new_exceptions && ! exceptions_via_longjmp)
+ return;
+
+ /* Under the old mechanism, as well as setjmp/longjmp, we need to
+ issue code to compare 'rtime' to the value in eh_info, via the
+ matching function in eh_info. If its is false, we branch around
+ the handler we are about to issue. */
+
+ if (rtime != NULL_TREE && rtime != CATCH_ALL_TYPE)
+ {
+ rtx call_rtx, rtime_address;
+
+ if (catchstack.top->entry->false_label != NULL_RTX)
+ error ("never issued previous false_label");
+ catchstack.top->entry->false_label = gen_exception_label ();
+
+ rtime_address = expand_expr (rtime, NULL_RTX, Pmode, EXPAND_INITIALIZER);
+ rtime_address = force_reg (Pmode, rtime_address);
+
+ /* Now issue the call, and branch around handler if needed */
+ call_rtx = emit_library_call_value (
+ gen_rtx_SYMBOL_REF (Pmode, "__eh_rtime_match"), NULL_RTX,
+ 0, SImode, 1, rtime_address, Pmode);
+
+ /* Did the function return true? */
+ emit_cmp_insn (call_rtx, const0_rtx, EQ, NULL_RTX,
+ GET_MODE (call_rtx), 0 ,0);
+ emit_jump_insn (gen_beq (catchstack.top->entry->false_label));
+ }
+}
+
+/* Called to end a catch clause. If we aren't using the new exception
+ model tabel mechanism, we need to issue the branch-around label
+ for the end of the catch block. */
+
+void
+end_catch_handler ()
+{
+ if (! doing_eh (1) || (flag_new_exceptions && ! exceptions_via_longjmp))
+ return;
+
+ /* A NULL label implies the catch clause was a catch all or cleanup */
+ if (catchstack.top->entry->false_label == NULL_RTX)
+ return;
+
+ emit_label (catchstack.top->entry->false_label);
+ catchstack.top->entry->false_label = NULL_RTX;
}
/* Generate RTL for the start of a group of catch clauses.
@@ -1693,9 +1742,6 @@ expand_start_all_catch ()
ehstack.top->entry->outer_context = outer_context;
}
- /* We also have to start the handler if we aren't using the new model. */
- if (! flag_new_exceptions)
- start_catch_handler (NULL);
}
/* Finish up the catch block. At this point all the insns for the
@@ -1927,6 +1973,9 @@ output_exception_table_entry (file, n)
POINTER_SIZE / BITS_PER_UNIT);
}
putc ('\n', file); /* blank line */
+ /* We only output the first label under the old scheme */
+ if (! flag_new_exceptions)
+ break;
}
}