Open llvmbot opened 6 years ago
As a workaround, can you add __attribute__((visibility("default")))
to the explicit instantiation? That's what one would do for DLLs on Windows to fix the same issue.
While I acknowledge that this is an ABI incompatbility, clang's behavior seems reasonable to me. As a user, I would be somewhat annoyed if I added explicit instantiations of unannotated, DSO-internal class and suddenly they ended up in .dynsym
.
We've been hit by this issue again in Boost.Filesystem.
GCC has extern template codecvt https://github.com/gcc-mirror/gcc/blob/9768d7eb98d3b5462e4423f806e241434a90648d/libstdc%2B%2B-v3/include/bits/codecvt.h#L480-L502
Attempt to use libstdc++ with -fvisibility=hidden
on Calng++ gives sanitizer errors: https://travis-ci.org/vinniefalco/beast/jobs/429373840#L1289
libs/filesystem/src/path_traits.cpp:76:14: runtime error:member call on address 0x60300001d740 which does not point to an object of type 'std::__codecvt_abstract_base<wchar_t, char, __mbstate_t>'
0x60300001d740: note:object is of type 'std::codecvt<wchar_t, char, __mbstate_t>'
02 00 80 1b 18 3e 73 1b 56 7f 00 00 01 00 00 00 be be be be 40 d2 00 00 30 61 00 00 00 00 00 00
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'std::codecvt<wchar_t, char, __mbstate_t>'
Extended Description
We have a problem in Boost.Regex where compiling with
clang++ -fvisibility=hidden
results in certain explicit template instantiations not being visible from the final shared library - while the same code with g++ is just fine. Further more the template instances are marked "W" in the object file, yet somehow still end up being hidden in the final.so
regardless of whether g++ or clang++ is used as the linker.I've tried pretty hard to boil this down to a simple test case - but miserably failed as all the simple cases work as expected. So the attached test case is our code pre-processed with g++, and can then be compiled with either g++ or clang.
To reproduce, build with:
Or
Then:
And search for "maybe_assign" - the g++ compiled
.so
will have two such records, while clang++ has none.