http://llvm.org/bugs/show_bug.cgi?id=19989
M.E. O'Neill <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Resolution|FIXED |--- --- Comment #8 from M.E. O'Neill <[email protected]> --- (In reply to comment #7) > Fixed in r210632. It doesn't quite produce the same output that earlier versions made, namely before we had: darwin% ~/llvm.199067/bin/clang++ -std=c++11 -stdlib=libc++ -c defn.cpp darwin% nm -m defn.o 0000000000000048 (__TEXT,__eh_frame) non-external EH_frame0 0000000000000000 (__TEXT,__text) private external __ZTW9perThread 0000000000000060 (__TEXT,__eh_frame) private external __ZTW9perThread.eh (undefined) external __tlv_bootstrap 000000000000000f (__DATA,__thread_vars) non-external _perThread 0000000000000088 (__DATA,__thread_bss) non-external _perThread$tlv$init and now we have darwin% ~/llvm.210637/bin/clang++ -std=c++11 -stdlib=libc++ -c defn.cpp darwin% nm -m defn.o 0000000000000048 (__TEXT,__eh_frame) non-external EH_frame0 0000000000000000 (__TEXT,__textcoal_nt) weak private external __ZTW9perThread 0000000000000060 (__TEXT,__eh_frame) weak private external __ZTW9perThread.eh (undefined) external __tlv_bootstrap 000000000000000f (__DATA,__thread_vars) non-external _perThread 0000000000000088 (__DATA,__thread_bss) non-external _perThread$tlv$init Thus, in the original __ZTW9perThread was not weak. Presumably the idea was that we know this is the definition of the variable and it can only appear here. (It might have to be weak if it were a template instantiation.) Pretty much regardless of this flaw, thread_local still seems to be broken, and perhaps has always been broken even since r180941. If we combine a translation unit that declares a thread_local variable with one that uses it, the end result doesn't link! For example, given defn.cpp as above and use.cpp as: extern thread_local int perThread; int main() { return perThread; } darwin% ~/llvm.210637/bin/clang++ -std=c++11 -stdlib=libc++ -c use.cpp darwin% nm -m use.o 0000000000000090 (__TEXT,__eh_frame) non-external EH_frame0 (undefined) weak external __ZTH9perThread 0000000000000020 (__TEXT,__textcoal_nt) weak private external __ZTW9perThread 00000000000000d0 (__TEXT,__eh_frame) weak private external __ZTW9perThread.eh 0000000000000000 (__TEXT,__text) external _main 00000000000000a8 (__TEXT,__eh_frame) external _main.eh (undefined) external _perThread darwin% ~/llvm.210637/bin/clang++ -std=c++11 -stdlib=libc++ -o prog defn.o use.o Undefined symbols for architecture x86_64: "__ZTH9perThread", referenced from: __ZTW9perThread in use.o "_perThread", referenced from: __ZTW9perThread in use.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) I see the same linker error with r182858 on the 3.3 branch, which is the oldest clang version for which I still have an executable. One part problem is that compiling use.cpp, it outputs a duplicate copy of the thread-wrapper function __ZTW9perThread even though that was already output, and that access function wants access to _perThread, which is non-external. Interestingly, the thread-wrapper generated for use.o is also more complicated, and calls a weakly-referenced function __ZTH9perThread (if it's non-null). This function is the thread-local init function -- presumably in the case of the definition, it knew that no such function was required. If instead it had relied on the code outputting the backing store for _perThread to output the wrapper function and not tried to make its own copy, it would have been fine. Thus, in this case, it would have been fine to have just said. .section __TEXT,__textcoal_nt,coalesced,pure_instructions .private_extern __ZTW9perThread .globl __ZTW9perThread .weak_reference __ZTW9perThread then it would have linked fine. There are also issues with templates; trying to hide the backing store interferes with coalescing resulting in duplicate copies of the storage and the initialization function. (It also has the same problem we saw earlier with emitting a broken wrapper for translation units where the thread-local variable is declared but not defined; again I think it should just not be doing that.) What I find strange in all this is that __thread gets all of these things right and works. While it's true that the rules for thread_local are a bit more complex because it allows dynamic initialization, it's not _that_ much different. -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ LLVMbugs mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/llvmbugs
