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;