stmt.c (expand_nl_goto_receiver): Copy hard register clobbers and ASM_INPUT barrier...
authorWaldek Hebisch <hebisch@math.uni.wroc.pl>
Fri, 5 Dec 2003 11:11:08 +0000 (12:11 +0100)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 5 Dec 2003 11:11:08 +0000 (03:11 -0800)
        * stmt.c (expand_nl_goto_receiver): Copy hard register clobbers
        and ASM_INPUT barrier from expand_builtin_setjmp_receiver.
* gcc.c-torture/execute/nestfunc-5.c: New.

From-SVN: r74326

gcc/ChangeLog
gcc/stmt.c
gcc/testsuite/gcc.c-torture/execute/nestfunc-5.c [new file with mode: 0644]

index e492f702dfde8ed53c312159378daa2715d0eaf9..1105644a9b76bac565e8aef882c1927a05ae6903 100644 (file)
@@ -1,3 +1,8 @@
+2003-12-05  Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+       * stmt.c (expand_nl_goto_receiver): Copy hard register clobbers
+       and ASM_INPUT barrier from expand_builtin_setjmp_receiver.
+
 2003-12-05  Richard Sandiford  <rsandifo@redhat.com>
 
        * config/mips/mips.c (mips_expand_call): Don't allow laziy binding
index 324789da312c6515653fa68ba0dd2e9e655aa8ba..bc52a6b096b2eb2d226c840f0dd40d9f3d553a57 100644 (file)
@@ -3558,6 +3558,14 @@ expand_nl_handler_label (rtx slot, rtx before_insn)
 static void
 expand_nl_goto_receiver (void)
 {
+    /* Clobber the FP when we get here, so we have to make sure it's
+     marked as used by this function.  */
+  emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
+
+  /* Mark the static chain as clobbered here so life information
+     doesn't get messed up for it.  */
+  emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
+
 #ifdef HAVE_nonlocal_goto
   if (! HAVE_nonlocal_goto)
 #endif
@@ -3606,6 +3614,13 @@ expand_nl_goto_receiver (void)
   if (HAVE_nonlocal_goto_receiver)
     emit_insn (gen_nonlocal_goto_receiver ());
 #endif
+
+  /* @@@ This is a kludge.  Not all machine descriptions define a blockage
+     insn, but we must not allow the code we just generated to be reordered
+     by scheduling.  Specifically, the update of the frame pointer must
+     happen immediately, not later.  So emit an ASM_INPUT to act as blockage
+     insn.  */
+  emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
 }
 
 /* Make handlers for nonlocal gotos taking place in the function calls in
diff --git a/gcc/testsuite/gcc.c-torture/execute/nestfunc-5.c b/gcc/testsuite/gcc.c-torture/execute/nestfunc-5.c
new file mode 100644 (file)
index 0000000..88e74cc
--- /dev/null
@@ -0,0 +1,36 @@
+extern void abort (void);
+extern void exit (int);
+
+#ifndef NO_TRAMPOLINES
+static void recursive (int n, void (*proc) (void))
+{
+  __label__ l1;
+
+  void do_goto (void)
+  {
+    goto l1;
+  }
+
+  if (n == 3)
+      recursive (n - 1, do_goto);
+  else if (n > 0)
+    recursive (n - 1, proc);
+  else
+    (*proc) ();
+  return;
+
+l1:
+  if (n == 3)
+    exit (0);
+  else
+    abort ();
+}
+
+int main ()
+{
+  recursive (10, abort);
+  abort ();
+}
+#else
+int main () { return 0; }
+#endif