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.

Reply via email to