diff --git a/libcxx/include/__availability b/libcxx/include/__availability --- a/libcxx/include/__availability +++ b/libcxx/include/__availability @@ -174,6 +174,15 @@ // # define _LIBCPP_AVAILABILITY_HAS_NO_PMR # define _LIBCPP_AVAILABILITY_PMR +// Enable additional explicit instantiations of iostreams components. This +// reduces the number of weak definitions generated in programs that use +// iostreams by providing a single strong definition in the shared library. +# define _LIBCPP_AVAILABILITY_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 + +// bad_function_call::what() with a string that is specific to +// bad_function_call (see https://wg21.link/LWG2233). +# define _LIBCPP_AVAILABILITY_ENABLE_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE_AND_KEY_FUNCTION + #elif defined(__APPLE__) // shared_mutex and shared_timed_mutex @@ -348,6 +357,14 @@ # define _LIBCPP_AVAILABILITY_PMR # endif +# if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 120000) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 150000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 150000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 80000) +# define _LIBCPP_AVAILABILITY_ENABLE_BAD_FUNCTION_CALL_KEY_FUNCTION +# define _LIBCPP_AVAILABILITY_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 +# endif + #else // ...New vendors can add availability markup here... diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -102,15 +102,6 @@ # define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB # define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB # define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE -// Define a key function for `bad_function_call` in the library, to centralize -// its vtable and typeinfo to libc++ rather than having all other libraries -// using that class define their own copies. -# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION -// Override the default return value of exception::what() for -// bad_function_call::what() with a string that is specific to -// bad_function_call (see http://wg21.link/LWG2233). This is an ABI break -// because it changes the vtable layout of bad_function_call. -# define _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE // Enable optimized version of __do_get_(un)signed which avoids redundant copies. # define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET // Give reverse_iterator one data member of type T, not two. @@ -156,6 +147,9 @@ // The implementation moved to the header, but we still export the symbols from // the dylib for backwards compatibility. # define _LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10 + +// Don't emit the destructor for bad_function_call in the dylib +# define _LIBCPP_ABI_NO_OUT_OF_LINE_BAD_FUNCTION_CALL_DESTRUCTOR # elif _LIBCPP_ABI_VERSION == 1 # if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF)) // Enable compiling copies of now inline methods into the dylib to support @@ -173,24 +167,13 @@ # if defined(__FreeBSD__) # define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR # endif -// For XCOFF linkers, we have problems if we see a weak hidden version of a symbol -// in user code (like you get with -fvisibility-inlines-hidden) and then a strong def -// in the library, so we need to always rely on the library version. -# if defined(_AIX) -# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION -# endif -# endif -# if defined(_LIBCPP_BUILDING_LIBRARY) || _LIBCPP_ABI_VERSION >= 2 -// Enable additional explicit instantiations of iostreams components. This -// reduces the number of weak definitions generated in programs that use -// iostreams by providing a single strong definition in the shared library. -# define _LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1 - -// Define a key function for `bad_function_call` in the library, to centralize -// its vtable and typeinfo to libc++ rather than having all other libraries -// using that class define their own copies. -# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION +// On most platforms we have always emitted a weak definition of the bad_function_call destructor. AIX is the only +// platform we support which doesn't contain the weak definitions. Because of that, removing it is only an ABI +// break on AIX. +# ifndef _AIX +# define _LIBCPP_ABI_NO_OUT_OF_LINE_BAD_FUNCTION_CALL_DESTRUCTOR +# endif # endif // Changes the iterator type of select containers (see below) to a bounded iterator that keeps track of whether it's diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h --- a/libcxx/include/__functional/function.h +++ b/libcxx/include/__functional/function.h @@ -60,13 +60,13 @@ // Note that when a key function is not used, every translation unit that uses // bad_function_call will end up containing a weak definition of the vtable and // typeinfo. -#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION - ~bad_function_call() _NOEXCEPT override; +#ifdef _LIBCPP_ABI_NO_OUT_OF_LINE_BAD_FUNCTION_CALL_DESTRUCTOR + _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override = default; #else - _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_function_call() _NOEXCEPT override {} + ~bad_function_call() _NOEXCEPT override; #endif -#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE +#ifdef _LIBCPP_AVAILABILITY_ENABLE_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE_AND_KEY_FUNCTION const char* what() const _NOEXCEPT override; #endif }; diff --git a/libcxx/include/fstream b/libcxx/include/fstream --- a/libcxx/include/fstream +++ b/libcxx/include/fstream @@ -1734,7 +1734,7 @@ this->setstate(ios_base::failbit); } -#if defined(_LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1) +#if defined(_LIBCPP_AVAILABILITY_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1) extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ifstream; extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ofstream; extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_filebuf; diff --git a/libcxx/include/sstream b/libcxx/include/sstream --- a/libcxx/include/sstream +++ b/libcxx/include/sstream @@ -1013,7 +1013,7 @@ __x.swap(__y); } -#if defined(_LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1) +#if defined(_LIBCPP_AVAILABILITY_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1) extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringbuf; extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_stringstream; extern template class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS basic_ostringstream; diff --git a/libcxx/src/functional.cpp b/libcxx/src/functional.cpp --- a/libcxx/src/functional.cpp +++ b/libcxx/src/functional.cpp @@ -10,18 +10,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION -bad_function_call::~bad_function_call() noexcept -{ -} +#ifndef _LIBCPP_ABI_NO_OUT_OF_LINE_BAD_FUNCTION_CALL_DESTRUCTOR +bad_function_call::~bad_function_call() noexcept {} #endif -#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE -const char* -bad_function_call::what() const noexcept -{ - return "std::bad_function_call"; -} -#endif +const char* bad_function_call::what() const noexcept { return "std::bad_function_call"; } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/src/ios.instantiations.cpp b/libcxx/src/ios.instantiations.cpp --- a/libcxx/src/ios.instantiations.cpp +++ b/libcxx/src/ios.instantiations.cpp @@ -31,7 +31,7 @@ #endif // Additional instantiations added later. Whether programs rely on these being -// available is protected by _LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1. +// available is protected by _LIBCPP_AVAILABILITY_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1. template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringbuf; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringstream; template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostringstream;