diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/builtins.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/eh/unwind1.C | 25 |
3 files changed, 37 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f9a3097cc92..1d413220720 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2006-09-12 Jason Merrill <jason@redhat.com> + + PR middle-end/28493 + * builtins.c (expand_builtin_setjmp_receiver): Clobber + hard_frame_pointer_rtx after using it to update the frame pointer. + 2006-09-12 Roger Sayle <roger@eyesopen.com> * target-def.h (TARGET_ASM_OPEN_PAREN): Guard with an #ifndef. diff --git a/gcc/builtins.c b/gcc/builtins.c index 5bcba14d7c2..4684a5482ad 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -679,7 +679,12 @@ expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED) #ifdef HAVE_nonlocal_goto if (! HAVE_nonlocal_goto) #endif - emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); + { + emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx); + /* This might change the hard frame pointer in ways that aren't + apparent to early optimization passes, so force a clobber. */ + emit_insn (gen_rtx_CLOBBER (VOIDmode, hard_frame_pointer_rtx)); + } #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM if (fixed_regs[ARG_POINTER_REGNUM]) diff --git a/gcc/testsuite/g++.dg/eh/unwind1.C b/gcc/testsuite/g++.dg/eh/unwind1.C new file mode 100644 index 00000000000..da7aa98fe59 --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/unwind1.C @@ -0,0 +1,25 @@ +// PR middle-end/28493 + +extern "C" void abort (); + +struct Command *ptr; + +struct Command { + Command() { ptr = this; } + virtual ~Command() { if (ptr != this) abort(); } +}; + +void tryfunc() +{ + Command cmd; + throw 1; +} + +int main() +{ + try + { + tryfunc(); + } + catch (int) { } +} |