From 32039f1945957cdd3ede4761757f66675401f0f9 Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Thu, 27 Mar 2025 12:02:39 +0100 Subject: [PATCH] [libc++] Add visibility annotations to the std namespace with GCC --- libcxx/docs/ReleaseNotes/21.rst | 5 ++++- libcxx/include/__config | 19 +++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst index 877aa06f8b7e4..7af109ddc8657 100644 --- a/libcxx/docs/ReleaseNotes/21.rst +++ b/libcxx/docs/ReleaseNotes/21.rst @@ -77,7 +77,10 @@ LLVM 22 ABI Affecting Changes --------------------- -- TODO +- When using GCC, the ``std`` namespace is now annotated with ``[[gnu::visibility("default")]]``. This may cause more + symbols to be exported from shared libraries when building with ``-fvisibility=hidden``. This also fixes RTTI + comparison between shared libraries, since all RTTI has the correct visibility now. There is no behaviour change on + Clang. Build System Changes diff --git a/libcxx/include/__config b/libcxx/include/__config index 35e62d0a19e85..ce8bc38acfe3e 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -386,7 +386,7 @@ typedef __char32_t char32_t; # define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS # define _LIBCPP_TEMPLATE_VIS # define _LIBCPP_TEMPLATE_DATA_VIS -# define _LIBCPP_TYPE_VISIBILITY_DEFAULT +# define _LIBCPP_NAMESPACE_VISIBILITY # else @@ -414,17 +414,16 @@ typedef __char32_t char32_t; # define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS # endif -// GCC doesn't support the type_visibility attribute, so we have to keep the visibility attribute on templates -# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && !__has_attribute(__type_visibility__) -# define _LIBCPP_TEMPLATE_VIS __attribute__((__visibility__("default"))) -# else -# define _LIBCPP_TEMPLATE_VIS -# endif +// This is kept to avoid a huge library-wide diff in the first step. +// TODO: Remove this in a follow-up patch +# define _LIBCPP_TEMPLATE_VIS # if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) && __has_attribute(__type_visibility__) -# define _LIBCPP_TYPE_VISIBILITY_DEFAULT __attribute__((__type_visibility__("default"))) +# define _LIBCPP_NAMESPACE_VISIBILITY __attribute__((__type_visibility__("default"))) +# elif !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_NAMESPACE_VISIBILITY __attribute__((__visibility__("default"))) # else -# define _LIBCPP_TYPE_VISIBILITY_DEFAULT +# define _LIBCPP_NAMESPACE_VISIBILITY # endif # endif // defined(_LIBCPP_OBJECT_FORMAT_COFF) @@ -583,7 +582,7 @@ typedef __char32_t char32_t; // If it's not clear whether using the unversioned namespace is the correct thing to do, it's not. The versioned // namespace (_LIBCPP_BEGIN_NAMESPACE_STD) should almost always be used. # define _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD \ - _LIBCPP_PUSH_EXTENSION_DIAGNOSTICS namespace _LIBCPP_TYPE_VISIBILITY_DEFAULT std { + _LIBCPP_PUSH_EXTENSION_DIAGNOSTICS namespace _LIBCPP_NAMESPACE_VISIBILITY std { # define _LIBCPP_END_UNVERSIONED_NAMESPACE_STD } _LIBCPP_POP_EXTENSION_DIAGNOSTICS