This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH to expand_builtin_setjmp_receiver for middle-end/28493
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 12 Sep 2006 13:56:24 -0400
- Subject: PATCH to expand_builtin_setjmp_receiver for middle-end/28493
The problem in 28493 turned out to be that we had
(set virtual-stack-vars hard-frame-pointer)
...
(compare virtual-stack-vars ptr)
devirtualization turned this into
(set soft-frame-pointer (minus hard-frame-pointer 8))
...
(set tmp (plus soft-frame-pointer 8))
(compare tmp ptr)
CSE cleverly changed the latter chunk to
(compare tmp hard-frame-pointer)
but then greg changes the first line to
(set hard-frame-pointer (minus hard-frame-pointer 8))
and things break. Fixed by forcing a clobber of the hard frame pointer
so that the soft/hard duality doesn't confuse CSE.
Tested powerpc-linux-gnu, applied to trunk.
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.
Index: builtins.c
===================================================================
*** builtins.c (revision 116898)
--- builtins.c (working copy)
*************** expand_builtin_setjmp_receiver (rtx rece
*** 679,685 ****
#ifdef HAVE_nonlocal_goto
if (! HAVE_nonlocal_goto)
#endif
! emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
if (fixed_regs[ARG_POINTER_REGNUM])
--- 679,690 ----
#ifdef HAVE_nonlocal_goto
if (! HAVE_nonlocal_goto)
#endif
! {
! 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])
Index: testsuite/g++.dg/eh/unwind1.C
===================================================================
*** testsuite/g++.dg/eh/unwind1.C (revision 0)
--- testsuite/g++.dg/eh/unwind1.C (revision 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) { }
+ }