GCC's ability to inline/clone self-recursive calls compromises the
find_stack_direction test in libiberty's configure.

The test essentially takes the address of a local in an outer and inner
context then compares their addresses to determine the direction of
stack growth.

Inlining causes the locals to be allocated in the same context which
totally defeats the purpose of the test.

This patch adds attributes to prevent inlining/cloning and rebuilds the
affected configure file.

Note there are configure files in other directories, but I'm pretty
sure they're using the cached value from libiberty and to fix them
requires an upstream fix to autoconf since those defintions don't come
from libiberty's aclocal.m4.

I'm particularly keen to get this in now as GCC is the master for
libiberty and Nick will be cutting a binutils release soon (and has
agreed to pull in this change already).  Getting the fix into binutils
now means the various copies in Fedora won't have to be patched
individually (mingw-binutils, avr-binutils, cross-binutils, arm-
whatever-binutils, nacl-binutils and possibly others).


You can see the effect by looking at how STACK_DIRECTION is defined in
config.h.  On x86 it should be "-1" and it is for the stage1 build if
you use an old enough compiler ;-)  But for stage2/stage3 it's "1"

Bootstrapped and regression tested on x86_64.  Verified STACK_DIRECTION
is correct via hand inspection.

OK for the trunk?
diff --git a/libiberty/aclocal.m4 b/libiberty/aclocal.m4
index bf8a907100f..381ed3b27e3 100644
--- a/libiberty/aclocal.m4
+++ b/libiberty/aclocal.m4
@@ -147,7 +147,7 @@ if test $ac_cv_os_cray = yes; then
 fi
 
 AC_CACHE_CHECK(stack direction for C alloca, ac_cv_c_stack_direction,
-[AC_TRY_RUN([find_stack_direction ()
+[AC_TRY_RUN([__attribute__ ((noclone,noinline)) find_stack_direction ()
 {
   static char *addr = 0;
   auto char dummy;
diff --git a/libiberty/configure b/libiberty/configure
index 7a34dabec32..e8391889cd7 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -6532,7 +6532,7 @@ else
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-find_stack_direction ()
+__attribute__ ((noclone,noinline)) find_stack_direction ()
 {
   static char *addr = 0;
   auto char dummy;

Reply via email to