diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -166,6 +166,12 @@ # 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 diff --git a/libcxx/test/libcxx/vendor/ibm/bad_function_call.pass.cpp b/libcxx/test/libcxx/vendor/ibm/bad_function_call.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/vendor/ibm/bad_function_call.pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// REQUIRES: target={{powerpc.*-ibm-aix.*}} +// ADDITIONAL_COMPILE_FLAGS: -fvisibility-inlines-hidden + +// When there is a weak hidden symbol in user code and a strong definition +// in the library, we test that the linker relies on the library version, +// as the default weak resolution semantics don't favour weak local definitions +// for XCOFF. This creates a conflict on std::bad_function_call, which is used +// by the std::function template instantiated in main. +#include +#include "test_macros.h" +#include "assert.h" + +void foo() {} + +void test_call() { + std::function r(foo); + r(); +} + +void test_throw() { +#ifndef TEST_HAS_NO_EXCEPTIONS + std::function f; + try { + f(); + assert(false); + } catch (const std::bad_function_call&) { + return; + } + assert(false); +#endif // TEST_HAS_NO_EXCEPTIONS +} + +int main(int, char**) { + test_call(); + test_throw(); + return 0; +}