Message ID | 20180719235838.qu33nbpp4c7ndc33@google.com |
---|---|
State | New |
Headers | show |
Series | Explicitly mark _S_ti() as default visibility to work around clang -fvisibility-inlines-hidden bug | expand |
On 19/07/18 16:58 -0700, Fāng-ruì Sòng via libstdc++ wrote: >clang (including trunk and many older versions) incorrectly marks static local variables (__tag) hidden when -fvisibility-inlines-hidden is used. > >% cat b.cc >#include <memory> >std::shared_ptr<int> foo(int x) { > return std::make_shared<int>(x); >} >% g++-8 -fvisibility-inlines-hidden -fno-rtti -c b.cc >% readelf -s b.o | grep _S_ti > 163: 0000000000000000 1 OBJECT UNIQUE DEFAULT 67 _ZZNSt19_Sp_make_shared_tag5_S_tiEvE5__tag > 164: 0000000000000000 8 FUNC WEAK HIDDEN 68 _ZNSt19_Sp_make_shared_tag5_S_tiEv >% ~/Dev/llvm/static-release/bin/clang++ -fvisibility-inlines-hidden -fno-rtti -c b.cc >% readelf -s b.o | grep _S_ti > 129: 0000000000000000 16 FUNC WEAK HIDDEN 34 _ZNSt19_Sp_make_shared_tag5_S_tiEv > 155: 0000000000000000 1 OBJECT WEAK HIDDEN 202 _ZZNSt19_Sp_make_shared_tag5_S_tiEvE5__tag > >This can lead to multiple instances of __tag when shares objects are used. >The function >virtual void* std::_Sp_counted_ptr_inplace::_M_get_deleter(const std::type_info& __ti) noexcept >may return nullptr and causes std::make_shared<T>() to return nullptr (-fvisibility-inlines-hidden -fno-rtti). > >After applying this patch (tagging _S_ti() with default visibility to override -fvisibility-inlines-hidden) > >% readelf -s b.o | grep _S_ti > 129: 0000000000000000 16 FUNC WEAK DEFAULT 34 _ZNSt19_Sp_make_shared_tag5_S_tiEv > 155: 0000000000000000 1 OBJECT WEAK DEFAULT 202 _ZZNSt19_Sp_make_shared_tag5_S_tiEvE5__tag > > >This issue caused 10+ check-all tests of a -DUSE_SHARED_LLVM=On build of llvm (compiled with clang trunk) to SIGSEGV (because std::make_shared returned nullptr) and this patch fixes it. > > > * include/bits/shared_ptr_base.h (_S_ti): Use > _GLIBCXX_VISIBILITY(default) > Thanks, I've tested this and committed it to trunk. I think we want this on gcc-8-branch too, but it's too late for the 8.2 release now. >-- >宋方睿 >From 6da8cec298766ce043d9c6dcda7b87142228dafb Mon Sep 17 00:00:00 2001 >From: Fangrui Song <maskray@google.com> >Date: Thu, 19 Jul 2018 16:40:26 -0700 >Subject: [PATCH 1/1] Explicitly mark _S_ti() as default visibility to work > around clang -fvisibility-inlines-hidden bug > >clang (including trunk and many older versions) incorrectly marks static >local variables (__tag) hidden when -fvisibility-inlines-hidden is used. >This can lead to multiple instances of __tag when shares objects are used. > > * include/bits/shared_ptr_base.h (_S_ti): Use > _GLIBCXX_VISIBILITY(default) >--- > libstdc++-v3/include/bits/shared_ptr_base.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h >index f3994da158f..870aeb9bfda 100644 >--- a/libstdc++-v3/include/bits/shared_ptr_base.h >+++ b/libstdc++-v3/include/bits/shared_ptr_base.h >@@ -508,7 +508,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > friend class _Sp_counted_ptr_inplace; > > static const type_info& >- _S_ti() noexcept >+ _S_ti() noexcept _GLIBCXX_VISIBILITY(default) > { > alignas(type_info) static constexpr _Sp_make_shared_tag __tag; > return reinterpret_cast<const type_info&>(__tag); >-- >2.18.0 >
diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index f3994da158f..870aeb9bfda 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -508,7 +508,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION friend class _Sp_counted_ptr_inplace; static const type_info& - _S_ti() noexcept + _S_ti() noexcept _GLIBCXX_VISIBILITY(default) { alignas(type_info) static constexpr _Sp_make_shared_tag __tag; return reinterpret_cast<const type_info&>(__tag);