This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Add _LIBCPP_TEMPLATE_VIS to __vector_base_common
Needs ReviewPublic

Authored by thomasanderson on Jul 12 2017, 1:55 PM.

Details

Summary

I built libc++ using gcc with -fvisibility=hidden, but when linking my app against the resulting libc++.so, I got this error:

../../buildtools/third_party/libc++/trunk/include/vector:964: error: undefined reference to 'std::1::vector_base_common<true>::__throw_length_error() const'

While this issue is also fixed by D35388, this CL tries to match the behavior to __string_base_common:
https://reviews.llvm.org/diffusion/L/browse/libcxx/trunk/include/string;307970$560

Diff Detail

Event Timeline

thomasanderson created this revision.Jul 12 2017, 1:55 PM
smeenai requested changes to this revision.Jul 13 2017, 9:38 AM
smeenai added a subscriber: smeenai.

This doesn't look right to me. _LIBCPP_TEMPLATE_VIS expands to __attribute__((__type_visibility__("default"))) on compilers where __type_visibility__ is supported; i.e., its intent is to only export the typeinfo and vtable. gcc doesn't support this attribute, so we'll use __visibility__ instead and this change will appear to fix your issue, but it's not conceptually correct.

All the types you're seeing link errors against have extern template instantiation declarations in the libc++ headers (and the corresponding instantiation definitions in the library itself). I think we may have a bug in our definition of _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS. Can you try applying P8003 and let me know if that fixes the link errors?

This revision now requires changes to proceed.Jul 13 2017, 9:38 AM

This doesn't look right to me. _LIBCPP_TEMPLATE_VIS expands to __attribute__((__type_visibility__("default"))) on compilers where __type_visibility__ is supported; i.e., its intent is to only export the typeinfo and vtable. gcc doesn't support this attribute, so we'll use __visibility__ instead and this change will appear to fix your issue, but it's not conceptually correct.

All the types you're seeing link errors against have extern template instantiation declarations in the libc++ headers (and the corresponding instantiation definitions in the library itself). I think we may have a bug in our definition of _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS. Can you try applying P8003 and let me know if that fixes the link errors?

That patch fixes the vector case but unfortunately operator+ for string is still not getting exported:
../../test/unittests/compiler-dispatcher/compiler-dispatcher-unittest.cc:580: error: undefined reference to 'std::1::basic_string<char, std::1::char_traits<char>, std::1::allocator<char> > std::1::operator+<char, std::1::char_traits<char>, std::1::allocator<char> >(char const*, std::1::basic_string<char, std::1::char_traits<char>, std::__1::allocator<char> > const&)'

Does P8004 fix operator+?

Does P8004 fix operator+?

Yes it does :)

Perfect. I'll throw up some patches.

Hmm, what version of gcc are you using? https://reviews.llvm.org/diffusion/L/browse/libcxx/trunk/docs/DesignDocs/VisibilityMacros.rst;307951$86-90 suggests this may have changed recently.

I'm using 4.8.4

Hmm, that's pretty ancient (and I would be surprised if that changed in newer versions). Lemme play with this some more.

Also, string has a class almost identical to __vector_base_common:
https://reviews.llvm.org/diffusion/L/browse/libcxx/trunk/include/string;307970$560

But currently string has _LIBCPP_TEMPLATE_VIS and vector does not. Maybe at least one of them is wrong?

r307966 fixes string operator+, and D35388 fixes __vector_base_common.

r307966 fixes string operator+, and D35388 fixes __vector_base_common.

Awesome, thanks for the quick fixes!

Also, string has a class almost identical to __vector_base_common:
https://reviews.llvm.org/diffusion/L/browse/libcxx/trunk/include/string;307970$560

But currently string has _LIBCPP_TEMPLATE_VIS and vector does not. Maybe at least one of them is wrong?

Hmm.

I feel that __string_base_common shouldn't be marked _LIBCPP_TEMPLATE_VIS. In the clang world, _LIBCPP_TEMPLATE_VIS marks the vtable and typeinfo with default visibility. The class won't have a vtable since it doesn't have any virtual functions. Typeinfo visibility should only matter if you're throwing types across dynamic library boundaries, but since __string_base_common is an internal type, that shouldn't be an issue anyway. @EricWF can weigh in on that when he sees this though.

r307966 fixes string operator+, and D35388 fixes __vector_base_common.

Awesome, thanks for the quick fixes!

I'm just glad someone else is also attempting to use libc++ with hidden visibility :)

@thomasanderson you could re-upload this diff with just the include/vector change, and then @EricWF can decide if that's the right thing to do.

thomasanderson edited edge metadata.
smeenai resigned from this revision.Jul 17 2017, 2:11 PM

You probably wanna update the summary. We also generally recommend uploading patches with more context (pass -U9999 to your git commands), though it doesn't make much difference over here.

thomasanderson retitled this revision from [libc++] Add _LIBCPP_TEMPLATE_VIS to string operator+ and __vector_base_common to [libc++] Add _LIBCPP_TEMPLATE_VIS to __vector_base_common.Jul 17 2017, 2:35 PM
thomasanderson edited the summary of this revision. (Show Details)

pinging EricWF
this CL is needed to fix ../../buildtools/third_party/libc++/trunk/include/vector:970: error: undefined reference to 'std::__1::__vector_base_common<true>::__throw_length_error() const'
https://logs.chromium.org/v/?s=chromium%2Fbb%2Ftryserver.v8%2Fv8_linux64_gcc_compile_dbg%2F10118%2F%2B%2Frecipes%2Fsteps%2Fcompile%2F0%2Fstdout

ldionne set the repository for this revision to rG LLVM Github Monorepo.Jan 12 2021, 7:10 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 12 2021, 7:10 AM