https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77329
Bug ID: 77329 Summary: gcc doesn't always correctly calculate label addresses Product: gcc Version: 6.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: dhowells at redhat dot com Target Milestone: --- The following code: extern int printf(const char *, ...); extern int A(int), B(int); int test(void) { A(0); foo: printf("%p\n", &&foo); B(0); return 99; } Incorrectly calculates the address of the label foo with -Os and -O2, but works fine with -O0. For -Os on an x86_64 cross-compiler or native compiler of version 6.1.1, I see: .LC0: .string "%p\n" test: .LFB0: .cfi_startproc .L2: subq $8, %rsp .cfi_def_cfa_offset 16 xorl %edi, %edi call A movl $.L2, %esi movl $.LC0, %edi xorl %eax, %eax call printf xorl %edi, %edi call B movl $99, %eax popq %rdx .cfi_def_cfa_offset 8 ret Note the .L2 label before the test function prologue - the address of this is &&foo. I would expect .L2 to appear between the first and second statements. .L2 does indeed appear there if the label address is placed in a variable and then passed to a goto-statement. Note that adding: asm("jmp *%0" : : "r"(here)); before the return doesn't help. The cross compiler is built thusly: configure --bindir=/usr/bin --build=x86_64-redhat-linux-gnu --datadir=/usr/share --disable-decimal-float --disable-dependency-tracking --disable-gold --disable-libgcj --disable-libgomp --disable-libmpx --disable-libquadmath --disable-libssp --disable-libunwind-exceptions --disable-shared --disable-silent-rules --disable-sjlj-exceptions --disable-threads --with-ld=/usr/bin/x86_64-linux-gnu-ld --enable-__cxa_atexit --enable-checking=release --enable-gnu-unique-object --enable-initfini-array --enable-languages=c,c++ --enable-linker-build-id --enable-lto --enable-nls --enable-obsolete --enable-plugin --enable-targets=all --exec-prefix=/usr --host=x86_64-redhat-linux-gnu --includedir=/usr/include --infodir=/usr/share/info --libexecdir=/usr/libexec --localstatedir=/var --mandir=/usr/share/man --prefix=/usr --program-prefix=x86_64-linux-gnu- --sbindir=/usr/sbin --sharedstatedir=/var/lib --sysconfdir=/etc --target=x86_64-linux-gnu --with-bugurl=http://bugzilla.redhat.com/bugzilla/ --with-isl --with-newlib --with-plugin-ld=/usr/bin/x86_64-linux-gnu-ld --with-sysroot=/usr/x86_64-linux-gnu/sys-root --with-system-libunwind --with-system-zlib --without-headers --with-arch_32=i686 --with-tune=generic --enable-gnu-indirect-function --with-linker-hash-style=gnu The compiler is 20160621, svn rev 237634.