re PR c/6358 (GCC 3.1 ICE on statement expressions)
authorJakub Jelinek <jakub@redhat.com>
Thu, 18 Apr 2002 19:10:11 +0000 (21:10 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 18 Apr 2002 19:10:11 +0000 (21:10 +0200)
PR c/6358
* function.c (assign_parms): Assign hard current_function_return_rtx
register here...
(expand_function_end): ...not here.

* gcc.c-torture/compile/20020418-1.c: New test.

From-SVN: r52485

gcc/ChangeLog
gcc/function.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20020418-1.c [new file with mode: 0644]

index 091231ed8a279b5cb13e97124628e2b6af75f61e..2676cb0036bd0bcac7c638e36b8a798bdf8e4f6e 100644 (file)
@@ -1,3 +1,10 @@
+2002-04-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/6358
+       * function.c (assign_parms): Assign hard current_function_return_rtx
+       register here...
+       (expand_function_end): ...not here.
+
 2002-04-18  Neil Booth  <neil@daikokuya.demon.co.uk>
 
        * c-lang.c (LANG_HOOKS_INCOMPLETE_TYPE_ERROR): Redefine.
index 86a87ab60683574c10daf8136d907418561b4d3f..4562376ce4980589310a48ad4dddc296e217f064 100644 (file)
@@ -5145,6 +5145,35 @@ assign_parms (fndecl)
   current_function_return_rtx
     = (DECL_RTL_SET_P (DECL_RESULT (fndecl))
        ? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX);
+
+  /* If scalar return value was computed in a pseudo-reg, or was a named
+     return value that got dumped to the stack, copy that to the hard
+     return register.  */
+  if (DECL_RTL_SET_P (DECL_RESULT (fndecl)))
+    {
+      tree decl_result = DECL_RESULT (fndecl);
+      rtx decl_rtl = DECL_RTL (decl_result);
+
+      if (REG_P (decl_rtl)
+         ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
+         : DECL_REGISTER (decl_result))
+       {
+         rtx real_decl_rtl;
+
+#ifdef FUNCTION_OUTGOING_VALUE
+         real_decl_rtl = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl_result),
+                                                  fndecl);
+#else
+         real_decl_rtl = FUNCTION_VALUE (TREE_TYPE (decl_result),
+                                         fndecl);
+#endif
+         REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
+         /* The delay slot scheduler assumes that current_function_return_rtx
+            holds the hard register containing the return value, not a
+            temporary pseudo.  */
+         current_function_return_rtx = real_decl_rtl;
+       }
+    }
 }
 \f
 /* Indicate whether REGNO is an incoming argument to the current function
@@ -6958,16 +6987,11 @@ expand_function_end (filename, line, end_bindings)
          ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
          : DECL_REGISTER (decl_result))
        {
-         rtx real_decl_rtl;
+         rtx real_decl_rtl = current_function_return_rtx;
 
-#ifdef FUNCTION_OUTGOING_VALUE
-         real_decl_rtl = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl_result),
-                                                  current_function_decl);
-#else
-         real_decl_rtl = FUNCTION_VALUE (TREE_TYPE (decl_result),
-                                         current_function_decl);
-#endif
-         REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
+         /* This should be set in assign_parms.  */
+         if (! REG_FUNCTION_VALUE_P (real_decl_rtl))
+           abort ();
 
          /* If this is a BLKmode structure being returned in registers,
             then use the mode computed in expand_return.  Note that if
@@ -6995,11 +7019,6 @@ expand_function_end (filename, line, end_bindings)
                             int_size_in_bytes (TREE_TYPE (decl_result)));
          else
            emit_move_insn (real_decl_rtl, decl_rtl);
-
-         /* The delay slot scheduler assumes that current_function_return_rtx
-            holds the hard register containing the return value, not a
-            temporary pseudo.  */
-         current_function_return_rtx = real_decl_rtl;
        }
     }
 
index 8798cc1eb69933bbe210bd2a272b90b802fac43e..9c6bd869be3b459e55377b379285a6a32ef9a042 100644 (file)
@@ -1,3 +1,7 @@
+2002-04-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.c-torture/compile/20020418-1.c: New test.
+
 2002-04-18  Roger Sayle  <roger@eyesopen.com>
 
        * gcc.c-torture/compile/20020415-1.c: New.
diff --git a/gcc/testsuite/gcc.c-torture/compile/20020418-1.c b/gcc/testsuite/gcc.c-torture/compile/20020418-1.c
new file mode 100644 (file)
index 0000000..df01e68
--- /dev/null
@@ -0,0 +1,18 @@
+/* PR c/6358
+   This testcase ICEd on IA-32 in foo, because current_function_return_rtx
+   was assigned a hard register only after expand_null_return was called,
+   thus return pseudo was clobbered twice and the hard register not at
+   all.  */
+
+void baz (void);
+                       
+double foo (void)
+{
+  baz ();
+  return;
+}
+
+double bar (void)
+{
+  baz ();
+}