[PATCH] Explicitly mark _S_ti() as default visibility to work around clang -fvisibility-inlines-hidden bug
Jonathan Wakely
jwakely@redhat.com
Fri Jul 20 11:24:00 GMT 2018
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
>
More information about the Libstdc++
mailing list