Index: include/utility =================================================================== --- include/utility +++ include/utility @@ -291,9 +291,20 @@ constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); #endif +#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) +struct __non_trivially_copyable_base { + _LIBCPP_CONSTEXPR _LIBCPP_INLINE_VISIBILITY + __non_trivially_copyable_base() _NOEXCEPT {} + _LIBCPP_CONSTEXPR_AFTER_CXX11 _LIBCPP_INLINE_VISIBILITY + __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {} +}; +#endif template struct _LIBCPP_TYPE_VIS_ONLY pair +#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) +: private __non_trivially_copyable_base +#endif { typedef _T1 first_type; typedef _T2 second_type; @@ -301,26 +312,7 @@ _T1 first; _T2 second; -#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) - _LIBCPP_INLINE_VISIBILITY - pair(const pair& __p) - _NOEXCEPT_(is_nothrow_copy_constructible::value && - is_nothrow_copy_constructible::value) - : first(__p.first), - second(__p.second) - { - } - -# ifndef _LIBCPP_CXX03_LANG - _LIBCPP_INLINE_VISIBILITY - pair(pair&& __p) _NOEXCEPT_(is_nothrow_move_constructible::value && - is_nothrow_move_constructible::value) - : first(_VSTD::forward(__p.first)), - second(_VSTD::forward(__p.second)) - { - } -# endif -#elif !defined(_LIBCPP_CXX03_LANG) +#if !defined(_LIBCPP_CXX03_LANG) pair(pair const&) = default; pair(pair&&) = default; #else Index: test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp =================================================================== --- test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp +++ test/libcxx/utilities/utility/pairs/pairs.pair/non_trivial_copy_move_ABI.pass.cpp @@ -7,49 +7,142 @@ // //===----------------------------------------------------------------------===// +// The test fails due to the missing is_trivially_constructible intrinsic. +// XFAIL: gcc-4.9 + // // template struct pair -// Test that we properly provide the old non-trivial copy operations -// when the ABI macro is defined. +// Test that we properly provide the trivial copy operations by default. +// FreeBSD provides the old ABI. This test checks the new ABI so we need +// to manually turn it on. +#undef _LIBCPP_ABI_UNSTABLE +#undef _LIBCPP_ABI_VERSION +#define _LIBCPP_ABI_VERSION 1 #define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR + #include +#include +#include #include #include "test_macros.h" +#if !defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR) +#error trivial ctor ABI macro defined +#endif + +template +struct HasNonTrivialABI : std::integral_constant::value + || (std::is_copy_constructible::value && !std::is_trivially_copy_constructible::value) +#if TEST_STD_VER >= 11 + || (std::is_move_constructible::value && !std::is_trivially_move_constructible::value) +#endif +> {}; + #if TEST_STD_VER >= 11 -struct Dummy { - Dummy(Dummy const&) = delete; - Dummy(Dummy &&) = default; +struct NonTrivialDtor { + NonTrivialDtor(NonTrivialDtor const&) = default; + ~NonTrivialDtor(); +}; +NonTrivialDtor::~NonTrivialDtor() {} +static_assert(HasNonTrivialABI::value, ""); + +struct NonTrivialCopy { + NonTrivialCopy(NonTrivialCopy const&); +}; +NonTrivialCopy::NonTrivialCopy(NonTrivialCopy const&) {} +static_assert(HasNonTrivialABI::value, ""); + +struct NonTrivialMove { + NonTrivialMove(NonTrivialMove const&) = default; + NonTrivialMove(NonTrivialMove&&); +}; +NonTrivialMove::NonTrivialMove(NonTrivialMove&&) {} +static_assert(HasNonTrivialABI::value, ""); + +struct DeletedCopy { + DeletedCopy(DeletedCopy const&) = delete; + DeletedCopy(DeletedCopy&&) = default; }; +static_assert(!HasNonTrivialABI::value, ""); + +struct TrivialMove { + TrivialMove(TrivialMove &&) = default; +}; +static_assert(!HasNonTrivialABI::value, ""); + +struct Trivial { + Trivial(Trivial const&) = default; +}; +static_assert(!HasNonTrivialABI::value, ""); #endif + int main() { - typedef std::pair P; { + typedef std::pair P; static_assert(std::is_copy_constructible

::value, ""); - static_assert(!std::is_trivially_copy_constructible

::value, ""); - static_assert(!std::is_trivially_copyable

::value, ""); + static_assert(HasNonTrivialABI

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

::value, ""); + static_assert(HasNonTrivialABI

::value, ""); + } + { + using P = std::pair; + static_assert(!std::is_trivially_destructible

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

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

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

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

::value, ""); + static_assert(HasNonTrivialABI

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

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

::value, ""); static_assert(std::is_move_constructible

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

::value, ""); - static_assert(!std::is_trivially_copyable

::value, ""); + static_assert(HasNonTrivialABI

::value, ""); } { - using P1 = std::pair; - // These lines fail because the non-trivial constructors do not provide - // SFINAE. - // static_assert(!std::is_copy_constructible::value, ""); - // static_assert(!std::is_trivially_copy_constructible::value, ""); - static_assert(std::is_move_constructible::value, ""); - static_assert(!std::is_trivially_move_constructible::value, ""); - static_assert(!std::is_trivially_copyable

::value, ""); + using P = std::pair; + static_assert(std::is_copy_constructible

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

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

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

::value, ""); + static_assert(HasNonTrivialABI

::value, ""); + } + { + using P = std::pair; + static_assert(!std::is_copy_constructible

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

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

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

::value, ""); + static_assert(HasNonTrivialABI

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

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

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

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

::value, ""); + static_assert(HasNonTrivialABI

::value, ""); + } + { + using P = std::pair; + static_assert(!std::is_copy_constructible

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

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

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

::value, ""); + static_assert(HasNonTrivialABI

::value, ""); } #endif }