diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -82,6 +82,11 @@ // 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 // In C++20 and later, don't derive std::plus from std::binary_function, @@ -127,6 +132,11 @@ // 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 #endif #define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y 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 @@ -35,10 +35,17 @@ class _LIBCPP_EXCEPTION_ABI bad_function_call : public exception { -#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION public: +// 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 virtual ~bad_function_call() _NOEXCEPT; +#else + virtual ~bad_function_call() _NOEXCEPT {} +#endif +#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE virtual const char* what() const _NOEXCEPT; #endif }; diff --git a/libcxx/lib/abi/CHANGELOG.TXT b/libcxx/lib/abi/CHANGELOG.TXT --- a/libcxx/lib/abi/CHANGELOG.TXT +++ b/libcxx/lib/abi/CHANGELOG.TXT @@ -12,6 +12,38 @@ New entries should be added directly below the "Version" header. +------------ +Version 14.0 +------------ + +* [libc++] Always define a key function for std::bad_function_call in the dylib + + This commit added a new explicit instantiation of std::bad_function_call's + vtable in the shared library. This change is not an ABI break as it only + adds symbols to the library. Programs compiled against the library will not + rely on the vtable being defined in it by default. Reliance on the vtable + being in the shared library can be enabled by defining the + _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION macro. + + x86_64-apple-apple-darwin + ------------------------- + Symbol added: __ZNSt3__117bad_function_callD0Ev + Symbol added: __ZNSt3__117bad_function_callD1Ev + Symbol added: __ZNSt3__117bad_function_callD2Ev + Symbol added: __ZTINSt3__117bad_function_callE + Symbol added: __ZTSNSt3__117bad_function_callE + Symbol added: __ZTVNSt3__117bad_function_callE + + x86_64-unknown-linux-gnu + ------------------------ + Symbol added: _ZNKSt9exception4whatEv + Symbol added: _ZNSt3__117bad_function_callD0Ev + Symbol added: _ZNSt3__117bad_function_callD1Ev + Symbol added: _ZNSt3__117bad_function_callD2Ev + Symbol added: _ZTINSt3__117bad_function_callE + Symbol added: _ZTSNSt3__117bad_function_callE + Symbol added: _ZTVNSt3__117bad_function_callE + ------------ Version 12.0 ------------ diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist --- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist +++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist @@ -1482,6 +1482,9 @@ {'is_defined': True, 'name': '__ZNSt3__117__widen_from_utf8ILm32EED0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117__widen_from_utf8ILm32EED1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117__widen_from_utf8ILm32EED2Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117declare_reachableEPv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117iostream_categoryEv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'} @@ -2025,6 +2028,7 @@ {'is_defined': True, 'name': '__ZTINSt3__117__assoc_sub_stateE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTINSt3__117__widen_from_utf8ILm16EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTINSt3__117__widen_from_utf8ILm32EEE', 'size': 0, 'type': 'OBJECT'} +{'is_defined': True, 'name': '__ZTINSt3__117bad_function_callE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTINSt3__117moneypunct_bynameIcLb0EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTINSt3__117moneypunct_bynameIcLb1EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTINSt3__117moneypunct_bynameIwLb0EEE', 'size': 0, 'type': 'OBJECT'} @@ -2198,6 +2202,7 @@ {'is_defined': True, 'name': '__ZTSNSt3__115time_get_bynameIwNS_19istreambuf_iteratorIwNS_11char_traitsIwEEEEEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTSNSt3__115time_put_bynameIcNS_19ostreambuf_iteratorIcNS_11char_traitsIcEEEEEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTSNSt3__115time_put_bynameIwNS_19ostreambuf_iteratorIwNS_11char_traitsIwEEEEEE', 'size': 0, 'type': 'OBJECT'} +{'is_defined': True, 'name': '__ZTSNSt3__117bad_function_callE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTSNSt3__117moneypunct_bynameIcLb0EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTSNSt3__117moneypunct_bynameIcLb1EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTSNSt3__117moneypunct_bynameIwLb0EEE', 'size': 0, 'type': 'OBJECT'} @@ -2398,6 +2403,7 @@ {'is_defined': True, 'name': '__ZTVNSt3__117__assoc_sub_stateE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTVNSt3__117__widen_from_utf8ILm16EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTVNSt3__117__widen_from_utf8ILm32EEE', 'size': 0, 'type': 'OBJECT'} +{'is_defined': True, 'name': '__ZTVNSt3__117bad_function_callE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTVNSt3__117moneypunct_bynameIcLb0EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTVNSt3__117moneypunct_bynameIcLb1EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTVNSt3__117moneypunct_bynameIwLb0EEE', 'size': 0, 'type': 'OBJECT'} diff --git a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist --- a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist +++ b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist @@ -1482,6 +1482,9 @@ {'is_defined': True, 'name': '__ZNSt3__117__widen_from_utf8ILm32EED0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117__widen_from_utf8ILm32EED1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117__widen_from_utf8ILm32EED2Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '__ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117declare_reachableEPv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117iostream_categoryEv', 'type': 'FUNC'} {'is_defined': True, 'name': '__ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'} @@ -2037,6 +2040,7 @@ {'is_defined': True, 'name': '__ZTINSt3__117__assoc_sub_stateE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTINSt3__117__widen_from_utf8ILm16EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTINSt3__117__widen_from_utf8ILm32EEE', 'size': 0, 'type': 'OBJECT'} +{'is_defined': True, 'name': '__ZTINSt3__117bad_function_callE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTINSt3__117moneypunct_bynameIcLb0EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTINSt3__117moneypunct_bynameIcLb1EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTINSt3__117moneypunct_bynameIwLb0EEE', 'size': 0, 'type': 'OBJECT'} @@ -2223,6 +2227,7 @@ {'is_defined': True, 'name': '__ZTSNSt3__115time_get_bynameIwNS_19istreambuf_iteratorIwNS_11char_traitsIwEEEEEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTSNSt3__115time_put_bynameIcNS_19ostreambuf_iteratorIcNS_11char_traitsIcEEEEEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTSNSt3__115time_put_bynameIwNS_19ostreambuf_iteratorIwNS_11char_traitsIwEEEEEE', 'size': 0, 'type': 'OBJECT'} +{'is_defined': True, 'name': '__ZTSNSt3__117bad_function_callE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTSNSt3__117moneypunct_bynameIcLb0EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTSNSt3__117moneypunct_bynameIcLb1EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTSNSt3__117moneypunct_bynameIwLb0EEE', 'size': 0, 'type': 'OBJECT'} @@ -2428,6 +2433,7 @@ {'is_defined': True, 'name': '__ZTVNSt3__117__assoc_sub_stateE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTVNSt3__117__widen_from_utf8ILm16EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTVNSt3__117__widen_from_utf8ILm32EEE', 'size': 0, 'type': 'OBJECT'} +{'is_defined': True, 'name': '__ZTVNSt3__117bad_function_callE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTVNSt3__117moneypunct_bynameIcLb0EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTVNSt3__117moneypunct_bynameIcLb1EEE', 'size': 0, 'type': 'OBJECT'} {'is_defined': True, 'name': '__ZTVNSt3__117moneypunct_bynameIwLb0EEE', 'size': 0, 'type': 'OBJECT'} diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist --- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist +++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist @@ -1,5 +1,6 @@ {'is_defined': False, 'name': '_ZNKSt11logic_error4whatEv', 'type': 'FUNC'} {'is_defined': False, 'name': '_ZNKSt13runtime_error4whatEv', 'type': 'FUNC'} +{'is_defined': False, 'name': '_ZNKSt9exception4whatEv', 'type': 'FUNC'} {'is_defined': False, 'name': '_ZNSt11logic_errorD2Ev', 'type': 'FUNC'} {'is_defined': False, 'name': '_ZNSt12length_errorD1Ev', 'type': 'FUNC'} {'is_defined': False, 'name': '_ZNSt12out_of_rangeD1Ev', 'type': 'FUNC'} @@ -1172,6 +1173,9 @@ {'is_defined': True, 'name': '_ZNSt3__117__widen_from_utf8ILm32EED0Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117__widen_from_utf8ILm32EED1Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117__widen_from_utf8ILm32EED2Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD0Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD1Ev', 'type': 'FUNC'} +{'is_defined': True, 'name': '_ZNSt3__117bad_function_callD2Ev', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117declare_reachableEPv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117iostream_categoryEv', 'type': 'FUNC'} {'is_defined': True, 'name': '_ZNSt3__117moneypunct_bynameIcLb0EE4initEPKc', 'type': 'FUNC'} @@ -1703,6 +1707,7 @@ {'is_defined': True, 'name': '_ZTINSt3__117__assoc_sub_stateE', 'size': 24, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTINSt3__117__widen_from_utf8ILm16EEE', 'size': 24, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTINSt3__117__widen_from_utf8ILm32EEE', 'size': 24, 'type': 'OBJECT'} +{'is_defined': True, 'name': '_ZTINSt3__117bad_function_callE', 'size': 24, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTINSt3__117moneypunct_bynameIcLb0EEE', 'size': 24, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTINSt3__117moneypunct_bynameIcLb1EEE', 'size': 24, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTINSt3__117moneypunct_bynameIwLb0EEE', 'size': 24, 'type': 'OBJECT'} @@ -1832,6 +1837,7 @@ {'is_defined': True, 'name': '_ZTSNSt3__117__assoc_sub_stateE', 'size': 28, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTSNSt3__117__widen_from_utf8ILm16EEE', 'size': 35, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTSNSt3__117__widen_from_utf8ILm32EEE', 'size': 35, 'type': 'OBJECT'} +{'is_defined': True, 'name': '_ZTSNSt3__117bad_function_callE', 'size': 28, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTSNSt3__117moneypunct_bynameIcLb0EEE', 'size': 35, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTSNSt3__117moneypunct_bynameIcLb1EEE', 'size': 35, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTSNSt3__117moneypunct_bynameIwLb0EEE', 'size': 35, 'type': 'OBJECT'} @@ -1962,6 +1968,7 @@ {'is_defined': True, 'name': '_ZTVNSt3__117__assoc_sub_stateE', 'size': 48, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTVNSt3__117__widen_from_utf8ILm16EEE', 'size': 96, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTVNSt3__117__widen_from_utf8ILm32EEE', 'size': 96, 'type': 'OBJECT'} +{'is_defined': True, 'name': '_ZTVNSt3__117bad_function_callE', 'size': 40, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTVNSt3__117moneypunct_bynameIcLb0EEE', 'size': 112, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTVNSt3__117moneypunct_bynameIcLb1EEE', 'size': 112, 'type': 'OBJECT'} {'is_defined': True, 'name': '_ZTVNSt3__117moneypunct_bynameIwLb0EEE', 'size': 112, 'type': 'OBJECT'} diff --git a/libcxx/src/functional.cpp b/libcxx/src/functional.cpp --- a/libcxx/src/functional.cpp +++ b/libcxx/src/functional.cpp @@ -14,7 +14,9 @@ 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 { diff --git a/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp b/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp --- a/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/copy.pass.cpp @@ -6,7 +6,18 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03 +// Address Sanitizer doesn't instrument weak symbols on Linux. When a key +// function is defined for bad_function_call's vtable, its typeinfo and vtable +// will be defined as strong symbols in the library and weak symbols in other +// translation units. Only the strong symbol will be instrumented, increasing +// its size (due to the redzone) and leading to a serious ODR violation +// resulting in a crash. +// Some relevant bugs: +// https://github.com/google/sanitizers/issues/1017 +// https://github.com/google/sanitizers/issues/619 +// https://github.com/google/sanitizers/issues/398 +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68016 +// UNSUPPORTED: c++03, asan // XFAIL: LIBCXX-AIX-FIXME // diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.pass.cpp --- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.inv/invoke.pass.cpp @@ -15,6 +15,19 @@ // This test runs in C++03, but we have deprecated using std::function in C++03. // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS +// Address Sanitizer doesn't instrument weak symbols on Linux. When a key +// function is defined for bad_function_call's vtable, its typeinfo and vtable +// will be defined as strong symbols in the library and weak symbols in other +// translation units. Only the strong symbol will be instrumented, increasing +// its size (due to the redzone) and leading to a serious ODR violation +// resulting in a crash. +// Some relevant bugs: +// https://github.com/google/sanitizers/issues/1017 +// https://github.com/google/sanitizers/issues/619 +// https://github.com/google/sanitizers/issues/398 +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68016 +// UNSUPPORTED: asan + #include #include diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp --- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp @@ -6,7 +6,18 @@ // //===----------------------------------------------------------------------===// -// UNSUPPORTED: c++03 +// Address Sanitizer doesn't instrument weak symbols on Linux. When a key +// function is defined for bad_function_call's vtable, its typeinfo and vtable +// will be defined as strong symbols in the library and weak symbols in other +// translation units. Only the strong symbol will be instrumented, increasing +// its size (due to the redzone) and leading to a serious ODR violation +// resulting in a crash. +// Some relevant bugs: +// https://github.com/google/sanitizers/issues/1017 +// https://github.com/google/sanitizers/issues/619 +// https://github.com/google/sanitizers/issues/398 +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68016 +// UNSUPPORTED: c++03, asan //