diff --git a/libcxx/include/__utility/pair.h b/libcxx/include/__utility/pair.h index 7e17c4c415c41..6f293e1b5d65c 100644 --- a/libcxx/include/__utility/pair.h +++ b/libcxx/include/__utility/pair.h @@ -267,6 +267,7 @@ struct _LIBCPP_TEMPLATE_VIS pair } # if _LIBCPP_STD_VER >= 23 + template _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair const& __p) const noexcept(is_nothrow_copy_assignable_v && is_nothrow_copy_assignable_v) requires(is_copy_assignable_v && is_copy_assignable_v) @@ -276,6 +277,7 @@ struct _LIBCPP_TEMPLATE_VIS pair return *this; } + template _LIBCPP_HIDE_FROM_ABI constexpr const pair& operator=(pair&& __p) const noexcept(is_nothrow_assignable_v && is_nothrow_assignable_v) diff --git a/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp similarity index 100% rename from libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp rename to libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp diff --git a/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp similarity index 79% rename from libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp rename to libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp index fe098a7af7e8f..3ec60c08b8eab 100644 --- a/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/trivial_copy_move_ABI.pass.cpp +++ b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/abi.trivial_copy_move.pass.cpp @@ -71,6 +71,17 @@ struct Trivial { static_assert(HasTrivialABI::value, ""); #endif +struct TrivialNoAssignment { + int arr[4]; + TrivialNoAssignment& operator=(const TrivialNoAssignment&) = delete; +}; + +struct TrivialNoConstruction { + int arr[4]; + TrivialNoConstruction() = default; + TrivialNoConstruction(const TrivialNoConstruction&) = delete; + TrivialNoConstruction& operator=(const TrivialNoConstruction&) = default; +}; void test_trivial() { @@ -135,6 +146,26 @@ void test_trivial() static_assert(HasTrivialABI

::value, ""); } #endif + { + using P = std::pair; + static_assert(std::is_trivially_copy_constructible

::value, ""); + static_assert(std::is_trivially_move_constructible

::value, ""); +#if TEST_STD_VER >= 11 // This is https://llvm.org/PR90605 + static_assert(!std::is_trivially_copy_assignable

::value, ""); + static_assert(!std::is_trivially_move_assignable

::value, ""); +#endif // TEST_STD_VER >= 11 + static_assert(std::is_trivially_destructible

::value, ""); + } + { + using P = std::pair; +#if TEST_STD_VER >= 11 + static_assert(!std::is_trivially_copy_constructible

::value, ""); + static_assert(!std::is_trivially_move_constructible

::value, ""); +#endif // TEST_STD_VER >= 11 + static_assert(!std::is_trivially_copy_assignable

::value, ""); + static_assert(!std::is_trivially_move_assignable

::value, ""); + static_assert(std::is_trivially_destructible

::value, ""); + } } void test_layout() { diff --git a/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp new file mode 100644 index 0000000000000..1132b3e5def18 --- /dev/null +++ b/libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/abi.trivially_copyable.compile.pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// +// This test pins down the ABI of std::pair with respect to being "trivially copyable". +// + +// This test doesn't work when the deprecated ABI to turn off pair triviality is enabled. +// See libcxx/test/libcxx/utilities/utility/pairs/pairs.pair/abi.non_trivial_copy_move.pass.cpp instead. +// UNSUPPORTED: libcpp-deprecated-abi-disable-pair-trivial-copy-ctor + +#include +#include + +#include "test_macros.h" + +struct trivially_copyable { + int arr[4]; +}; + +struct trivially_copyable_no_copy_assignment { + int arr[4]; + trivially_copyable_no_copy_assignment& operator=(const trivially_copyable_no_copy_assignment&) = delete; +}; +static_assert(std::is_trivially_copyable::value, ""); + +struct trivially_copyable_no_move_assignment { + int arr[4]; + trivially_copyable_no_move_assignment& operator=(const trivially_copyable_no_move_assignment&) = delete; +}; +static_assert(std::is_trivially_copyable::value, ""); + +struct trivially_copyable_no_construction { + int arr[4]; + trivially_copyable_no_construction() = default; + trivially_copyable_no_construction(const trivially_copyable_no_construction&) = delete; + trivially_copyable_no_construction& operator=(const trivially_copyable_no_construction&) = default; +}; +static_assert(std::is_trivially_copyable::value, ""); + +static_assert(!std::is_trivially_copyable >::value, ""); +static_assert(!std::is_trivially_copyable >::value, ""); +static_assert(!std::is_trivially_copyable >::value, ""); + +static_assert(!std::is_trivially_copyable >::value, ""); +static_assert(!std::is_trivially_copyable >::value, ""); +static_assert(!std::is_trivially_copyable >::value, ""); +static_assert(!std::is_trivially_copyable, int> >::value, ""); +static_assert(!std::is_trivially_copyable >::value, ""); +#if TEST_STD_VER == 03 // Known ABI difference +static_assert(!std::is_trivially_copyable >::value, ""); +static_assert(!std::is_trivially_copyable >::value, ""); +#else +static_assert(std::is_trivially_copyable >::value, ""); +static_assert(std::is_trivially_copyable >::value, ""); +#endif +static_assert(!std::is_trivially_copyable >::value, ""); + +static_assert(std::is_trivially_copy_constructible >::value, ""); +static_assert(std::is_trivially_move_constructible >::value, ""); +static_assert(!std::is_trivially_copy_assignable >::value, ""); +static_assert(!std::is_trivially_move_assignable >::value, ""); +static_assert(std::is_trivially_destructible >::value, ""); diff --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py index 7ac66d449b1cf..624a00d7e8ed3 100644 --- a/libcxx/utils/libcxx/test/dsl.py +++ b/libcxx/utils/libcxx/test/dsl.py @@ -308,8 +308,8 @@ def compilerMacros(config, flags=""): with open(test.getSourcePath(), "w") as sourceFile: sourceFile.write( """ - #if __has_include(<__config_site>) - # include <__config_site> + #if __has_include(<__config>) + # include <__config> #endif """ ) diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py index 7a9631a56e4bb..28c9c35ae9f87 100644 --- a/libcxx/utils/libcxx/test/features.py +++ b/libcxx/utils/libcxx/test/features.py @@ -335,10 +335,10 @@ def _mingwSupportsModules(cfg): ] # Deduce and add the test features that that are implied by the #defines in -# the <__config_site> header. +# the <__config> header. # # For each macro of the form `_LIBCPP_XXX_YYY_ZZZ` defined below that -# is defined after including <__config_site>, add a Lit feature called +# is defined after including <__config>, add a Lit feature called # `libcpp-xxx-yyy-zzz`. When a macro is defined to a specific value # (e.g. `_LIBCPP_ABI_VERSION=2`), the feature is `libcpp-xxx-yyy-zzz=`. # @@ -352,6 +352,7 @@ def _mingwSupportsModules(cfg): "_LIBCPP_NO_VCRUNTIME": "libcpp-no-vcruntime", "_LIBCPP_ABI_VERSION": "libcpp-abi-version", "_LIBCPP_ABI_BOUNDED_ITERATORS": "libcpp-has-abi-bounded-iterators", + "_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR": "libcpp-deprecated-abi-disable-pair-trivial-copy-ctor", "_LIBCPP_HAS_NO_FILESYSTEM": "no-filesystem", "_LIBCPP_HAS_NO_RANDOM_DEVICE": "no-random-device", "_LIBCPP_HAS_NO_LOCALIZATION": "no-localization",