[llvm-bugs] [Bug 35239] New: extern template classes, clang produces object code with 1 weak symbol, but ld gives undefined reference (ld accepts gcc object code)

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Nov 7 21:10:55 PST 2017


https://bugs.llvm.org/show_bug.cgi?id=35239

            Bug ID: 35239
           Summary: extern template classes, clang produces object code
                    with 1 weak symbol, but ld gives undefined reference
                    (ld accepts gcc object code)
           Product: new-bugs
           Version: 5.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: jamespharvey20 at gmail.com
                CC: llvm-bugs at lists.llvm.org

With the commands and files below, the linker thinks there's an undefined
reference to "demo<int>::demo(int)", but it's in file2.o as a weak symbol.  g++
7.2.0 links an executable that runs fine.

My guess is when it's linking file1.o and sees the constructor as unlinked,
that it errors there without checking if it exists elsewhere.

clang properly handles extern template functions, but not extern template
classes.

Note clang gives the linker error both with "-std=c++11" and "-std=c++17".



$ clang++ -std=c++11 file1.cpp -c -o file1.o

$ clang++ -std=c++11 file2.cpp -c -o file2.o

$ clang++ -std=c++11 file1.o file2.o -o file
file1.o: In demoction `f()':
file1.cpp:(.text+0x1f): undefined reference to `demo<int>::demo(int)'
clang-5.0: error: linker command failed with exit code 1 (use -v to see
invocation)

$ clang++ -std=c++11 file2.o file1.o -o file -v
clang version 5.0.0 (tags/RELEASE_500/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-pc-linux-gnu/7.2.0
Found candidate GCC installation:
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-pc-linux-gnu/7.2.0
Found candidate GCC installation: /usr/lib64/gcc/x86_64-pc-linux-gnu/7.2.0
Selected GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.0
Candidate multilib: .;@m64
Selected multilib: .;@m64
 "/usr/bin/ld" -pie --eh-frame-hdr -m elf_x86_64 -dynamic-linker
/lib64/ld-linux-x86-64.so.2 -o file
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.0/../../../../lib64/Scrt1.o
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.0/../../../../lib64/crti.o
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.0/crtbeginS.o
-L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.0
-L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.0/../../../../lib64
-L/usr/bin/../lib64 -L/lib/../lib64 -L/usr/lib/../lib64
-L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.0/../../.. -L/usr/bin/../lib
-L/lib -L/usr/lib file2.o file1.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.0/crtendS.o
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.0/../../../../lib64/crtn.o
file1.o: In demoction `f()':
file1.cpp:(.text+0x1f): undefined reference to `demo<int>::demo(int)'
clang-5.0: error: linker command failed with exit code 1 (use -v to see
invocation)

$ nm --demangle file1.o
                 U __stack_chk_fail
0000000000000000 T f()
                 U demo<int>::demo(int)

$ nm --demangle file2.o
0000000000000050 T main
                 U __stack_chk_fail
                 U f()
0000000000000000 T g()
0000000000000000 W demo<int>::demo(int)

Compare to gcc's object code: (note gcc's compiler creates 2 weak symbols,
which doesn't seem right to me either, but it properly links, and what I think
is a local debugging symbol)

$ nm --demangle file2.o {on gcc's object file}
                 U _GLOBAL_OFFSET_TABLE_
000000000000003f T main
                 U __stack_chk_fail
                 U f()
0000000000000000 T g()
0000000000000000 W demo<int>::demo(int)
0000000000000000 W demo<int>::demo(int)
0000000000000000 n demo<int>::demo(int)



--- header.h ---
#pragma once

template<typename T>
class demo {
public:
   demo(T _) : value(_) {}
private:
   T value;
};

--- file1.cpp ---
#include "header.h"

extern template class demo<int>;

void f() {
   demo<int> i{42};
}

--- file2.cpp ---
#include "header.h"

void f();
void g() {
   demo<int> j{23};
}

int main() {
   f();
   g();
}

-- 
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/20171108/c43f934b/attachment.html>


More information about the llvm-bugs mailing list