diff options
author | Andrew MacLeod <amacleod@cygnus.com> | 1998-09-15 11:20:52 +0000 |
---|---|---|
committer | Andrew Macleod <amacleod@gcc.gnu.org> | 1998-09-15 11:20:52 +0000 |
commit | bf71cd2eaa2d7091cd02f429beeec279b6a5c52d (patch) | |
tree | 6b24980704695c7ec0f059391cfe4c686deb5c76 /gcc/except.c | |
parent | 8a21007c9409ad2be041c05c304295ff449538b7 (diff) | |
download | gcc-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.c | 55 |
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; } } |