On Fri, Jun 17, 2011 at 13:21, Andy Wingo <wi...@pobox.com> wrote: > Hello, > > The following transcript indicates a problem with the stack growth > direction check, present at functions.m4:328 in autoconf 2.68: > > wingo@badger:/tmp$ cat foo.c > int > find_stack_direction () > { > static char *addr = 0;
Try to rewrite this line as volatile static char *addr = 0; It should help. > auto char dummy; > if (addr == 0) > { > addr = &dummy; > return find_stack_direction (); > } > else > return (&dummy > addr) ? 1 : -1; > } > > int > main () > { > return find_stack_direction () < 0; > } > wingo@badger:/tmp$ gcc -O1 -o test foo.c > wingo@badger:/tmp$ ./test; echo $? > 1 > wingo@badger:/tmp$ gcc -O3 -o test foo.c > wingo@badger:/tmp$ ./test; echo $? > 0 > $ gcc --version > gcc (Debian 4.6.0-13) 4.6.1 20110611 (prerelease) > Copyright (C) 2011 Free Software Foundation, Inc. > This is free software; see the source for copying conditions. There is NO > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. > > As you see, the check (on an x86-64 system) gives the correct result at > -O1 but not at -O3. > > (I don't actually use this check from _AC_LIBOBJ_ALLOCA, but Guile has > the exact same test to check for stack growth direction, so it's the > same issue. Reported by Marco Maggi.) > > Looking a bit more closely at this, I find the assembly to be a bit odd > here: > > 00000000004004a0 <find_stack_direction>: > 4004a0: mov 0x2003f9(%rip),%rax # 6008a0 <addr.1586> > 4004a7: test %rax,%rax > 4004aa: je 4004c0 <find_stack_direction+0x20> > 4004ac: lea -0x2(%rsp),%rdx > 4004b1: cmp %rdx,%rax > 4004b4: sbb %eax,%eax > 4004b6: and $0x2,%eax > 4004b9: sub $0x1,%eax > 4004bc: retq > 4004bd: nopl (%rax) > 4004c0: lea -0x2(%rsp),%rax > 4004c5: lea -0x1(%rsp),%rdx > 4004ca: cmp %rdx,%rax > 4004cd: mov %rax,0x2003cc(%rip) # 6008a0 <addr.1586> > 4004d4: sbb %eax,%eax > 4004d6: and $0x2,%eax > 4004d9: sub $0x1,%eax > 4004dc: retq > 4004dd: nop > 4004de: nop > 4004df: nop > > As you can see there is no call. The test will always be true, thus the > second branch is always taken. I don't know what allows GCC to do this > inlining. Could it be a GCC bug? Every time I think I have a GCC bug > I'm wrong, though :) No. It indeed traceable. Just start from main() and you will have full trace even with pen and paper. > > I tried changing the test to the following: > > int > find_stack_direction (char *addr) > { > char dummy; > if (addr == 0) > return find_stack_direction (&dummy); > else > return (&dummy > addr) ? 1 : -1; > } > > int > main () > { > return find_stack_direction (0) < 0; > } > > But I get the same behavior. Just because it still traceable :-) And modern Gcc is smart enough for do it :-) -- Andrew W. Nosenko <andrew.w.nose...@gmail.com>