re PR target/6420 (libstdc++ failures on sparc-linux-gnu)
authorDavid S. Miller <davem@redhat.com>
Wed, 24 Apr 2002 16:58:12 +0000 (09:58 -0700)
committerDavid S. Miller <davem@gcc.gnu.org>
Wed, 24 Apr 2002 16:58:12 +0000 (09:58 -0700)
2002-04-24  David S. Miller  <davem@redhat.com>

PR target/6420
* config/sparc/sparc.h (FUNCTION_OK_FOR_SIBCALL): Return false if
32-bit Sparc and current_function_returns_struct is true.

From-SVN: r52720

gcc/ChangeLog
gcc/config/sparc/sparc.h

index 2c90a625e30c0371d8470f500a866c95209ee015..8482554c725afa24a5358f0ca0fe16e67acacece 100644 (file)
@@ -1,3 +1,9 @@
+2002-04-24  David S. Miller  <davem@redhat.com>
+
+       PR target/6420
+       * config/sparc/sparc.h (FUNCTION_OK_FOR_SIBCALL): Return false if
+       32-bit Sparc and current_function_returns_struct is true.
+
 Wed Apr 24 13:48:25 CEST 2002  Jan Hubicka  <jh@suse.cz>
 
        * loop.c (canonicalize_condition): Use gen_int_mode.
index 4552132743adb44cb17408e550d75b49e7eee942..872b1eeeee05745bec69620404d25adac730fc60 100644 (file)
@@ -1902,8 +1902,23 @@ do {                                                                     \
 #define STRICT_ARGUMENT_NAMING TARGET_V9
 
 /* We do not allow sibling calls if -mflat, nor
-   we do not allow indirect calls to be optimized into sibling calls.  */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) (DECL && ! TARGET_FLAT)
+   we do not allow indirect calls to be optimized into sibling calls.
+
+   Also, on sparc 32-bit we cannot emit a sibling call when the
+   current function returns a structure.  This is because the "unimp
+   after call" convention would cause the callee to return to the
+   wrong place.  The generic code already disallows cases where the
+   function being called returns a structure.
+
+   It may seem strange how this last case could occur.  Usually there
+   is code after the call which jumps to epilogue code which dumps the
+   return value into the struct return area.  That ought to invalidate
+   the sibling call right?  Well, in the c++ case we can end up passing
+   the pointer to the struct return area to a constructor (which returns
+   void) and then nothing else happens.  Such a sibling call would look
+   valid without the added check here.  */
+#define FUNCTION_OK_FOR_SIBCALL(DECL) \
+       (! TARGET_FLAT && (TARGET_ARCH64 || ! current_function_returns_struct))
 
 /* Generate RTL to flush the register windows so as to make arbitrary frames
    available.  */