[LLVMbugs] [Bug 21786] New: clang comparing symbols from linker script wrong

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Dec 9 01:29:28 PST 2014


http://llvm.org/bugs/show_bug.cgi?id=21786

            Bug ID: 21786
           Summary: clang comparing symbols from linker script wrong
           Product: clang
           Version: 3.5
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: -New Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: bogachev.pa at gmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

Created attachment 13441
  --> http://llvm.org/bugs/attachment.cgi?id=13441&action=edit
objdump outputs of second example compiled with clang and with gcc

I'm trying to compare symbols defined in default linker script. The symbols are
pointing to the same address.

Consider the following code.

foo.c:

#include <stdio.h>

int main(void)
{
    extern void (*__preinit_array_start) ();
    extern void (*__preinit_array_end) ();

    if (&__preinit_array_start != &__preinit_array_end) {
        printf("%p != %p\n", &__preinit_array_start, &__preinit_array_end);
    } else {
        printf("%p == %p\n", &__preinit_array_start, &__preinit_array_end);
    }

    return 0;
}

Now I compile it with clang and run.
clang foo.c -o test-clang.o
./test-clang.o emits the following output:

0x600e0c != 0x600e0c

If I compile it with gcc I get:

0x600e0c == 0x600e0c

Both clang and gcc are from Ubuntu repositories.
clang --version
Ubuntu clang version 3.5-1ubuntu1 (trunk) (based on LLVM 3.5)
Target: x86_64-pc-linux-gnu
gcc --version
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2


Additional info:
I did a small research and it seems that clang optimizes out (even with -O0)
such comparison deciding that addresses of exported symbols can't be the same.

Consider the following simplification of the program above:

void foo(void);

void bar(void);

int main(void)
{
    extern void (*__preinit_array_start) ();
    extern void (*__preinit_array_end) ();

    if (&__preinit_array_start != &__preinit_array_end) {
        foo();
    } else {
        bar();
    }

    return 0;
}

Now I compile it (without linking) with clang and with gcc for arm (just
because I understand arm assembly slightly better) and compare objdumps (in
attachment).
You can clearly see that clang skipped the "bar" branch completely.

For that I used prebuilt clang and gcc from android ndk r10c.

android-ndk-r10c/toolchains/llvm-3.5/prebuilt/linux-x86_64/bin/clang -target
arm-linux-androideabi --version
clang version 3.5 
Target: arm--linux-androideabi

android-ndk-r10c/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
--version
arm-linux-androideabi-gcc (GCC) 4.8

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20141209/fb41421e/attachment.html>


More information about the llvm-bugs mailing list