diff options
author | obrien <obrien@FreeBSD.org> | 2001-03-24 01:58:31 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2001-03-24 01:58:31 +0000 |
commit | 83655f473eb53a186bdcf7f5f8f2927225bb39d0 (patch) | |
tree | 4e15b74819832174dd1510759ff5bf2e2cb921a9 /contrib/gcc/except.c | |
parent | b2d278bd47d90165e571cf2b9529c2ef154c5c4a (diff) | |
download | FreeBSD-src-83655f473eb53a186bdcf7f5f8f2927225bb39d0.zip FreeBSD-src-83655f473eb53a186bdcf7f5f8f2927225bb39d0.tar.gz |
Import the setjump/longjump exception handling fixes from GCC 2.95.3.test3
that were removed from GCC 2.95.3.test4 and the subsequent release due
to problems on HP-UX. However, they work just fine on all the BSD's.
W/o these patches the following program segmentation faults if compiled
with -O2 (but not -Os or -O or -O0):
#include <stdio.h>
class A {
public:
A() { printf("c'tor A\n"); }
~A(){ printf("d'tor A\n"); }
};
class foo : public A {
public:
foo() { printf("C'tor foo\n"); throw 8; }
~foo() { printf("D'tor foo\n"); }
};
int main(){
try { foo fii; }
catch (int){ printf("catch ...\n"); }
return 0;
}
Diffstat (limited to 'contrib/gcc/except.c')
-rw-r--r-- | contrib/gcc/except.c | 57 |
1 files changed, 38 insertions, 19 deletions
diff --git a/contrib/gcc/except.c b/contrib/gcc/except.c index f7d78d6..cc6fc29 100644 --- a/contrib/gcc/except.c +++ b/contrib/gcc/except.c @@ -723,21 +723,41 @@ static void receive_exception_label (handler_label) rtx handler_label; { + rtx around_label = NULL_RTX; + + if (! flag_new_exceptions || exceptions_via_longjmp) + { + around_label = gen_label_rtx (); + emit_jump (around_label); + emit_barrier (); + } + emit_label (handler_label); -#ifdef HAVE_exception_receiver if (! exceptions_via_longjmp) - if (HAVE_exception_receiver) - emit_insn (gen_exception_receiver ()); + { +#ifdef HAVE_exception_receiver + if (HAVE_exception_receiver) + emit_insn (gen_exception_receiver ()); + else #endif - #ifdef HAVE_nonlocal_goto_receiver - if (! exceptions_via_longjmp) - if (HAVE_nonlocal_goto_receiver) - emit_insn (gen_nonlocal_goto_receiver ()); + if (HAVE_nonlocal_goto_receiver) + emit_insn (gen_nonlocal_goto_receiver ()); + else #endif -} + { /* Nothing */ } + } + else + { +#ifndef DONT_USE_BUILTIN_SETJMP + expand_builtin_setjmp_receiver (handler_label); +#endif + } + if (around_label) + emit_label (around_label); +} struct func_eh_entry { @@ -1320,7 +1340,7 @@ static void start_dynamic_handler () { rtx dhc, dcc; - rtx x, arg, buf; + rtx arg, buf; int size; #ifndef DONT_USE_BUILTIN_SETJMP @@ -1362,18 +1382,17 @@ start_dynamic_handler () buf = plus_constant (XEXP (arg, 0), GET_MODE_SIZE (Pmode)*2); #ifdef DONT_USE_BUILTIN_SETJMP - x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1, SImode, 1, - buf, Pmode); - /* If we come back here for a catch, transfer control to the handler. */ - jumpif_rtx (x, ehstack.top->entry->exception_handler_label); -#else { - /* A label to continue execution for the no exception case. */ - rtx noex = gen_label_rtx(); - x = expand_builtin_setjmp (buf, NULL_RTX, noex, - ehstack.top->entry->exception_handler_label); - emit_label (noex); + rtx x; + x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_CONST, + TYPE_MODE (integer_type_node), 1, + buf, Pmode); + /* If we come back here for a catch, transfer control to the handler. */ + jumpif_rtx (x, ehstack.top->entry->exception_handler_label); } +#else + expand_builtin_setjmp_setup (buf, + ehstack.top->entry->exception_handler_label); #endif /* We are committed to this, so update the handler chain. */ |