Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc++] Revert "Make std::pair trivially copyable if its members are (#89652)" #100184

Merged
merged 1 commit into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions libcxx/include/__configuration/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,6 @@
// and WCHAR_MAX. This ABI setting determines whether we should instead track whether the fill
// value has been initialized using a separate boolean, which changes the ABI.
# define _LIBCPP_ABI_IOS_ALLOW_ARBITRARY_FILL_VALUE
// Make a std::pair of trivially copyable types trivially copyable.
// While this technically doesn't change the layout of pair itself, other types may decide to programatically change
// their representation based on whether something is trivially copyable.
# define _LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR
#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
Expand Down
1 change: 0 additions & 1 deletion libcxx/include/__type_traits/datasizeof.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ struct _FirstPaddingByte<_Tp, true> {
// the use as an extension.
_LIBCPP_DIAGNOSTIC_PUSH
_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Winvalid-offsetof")
_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Winvalid-offsetof")
template <class _Tp>
inline const size_t __datasizeof_v = offsetof(_FirstPaddingByte<_Tp>, __first_padding_byte_);
_LIBCPP_DIAGNOSTIC_POP
Expand Down
46 changes: 5 additions & 41 deletions libcxx/include/__utility/pair.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <__type_traits/is_implicitly_default_constructible.h>
#include <__type_traits/is_nothrow_assignable.h>
#include <__type_traits/is_nothrow_constructible.h>
#include <__type_traits/is_reference.h>
#include <__type_traits/is_same.h>
#include <__type_traits/is_swappable.h>
#include <__type_traits/is_trivially_relocatable.h>
Expand Down Expand Up @@ -81,38 +80,6 @@ struct _LIBCPP_TEMPLATE_VIS pair
_LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
_LIBCPP_HIDE_FROM_ABI pair(pair&&) = default;

// When we are requested for pair to be trivially copyable by the ABI macro, we use defaulted members
// if it is both legal to do it (i.e. no references) and we have a way to actually implement it, which requires
// the __enable_if__ attribute before C++20.
#ifdef _LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR
// FIXME: This should really just be a static constexpr variable. It's in a struct to avoid gdb printing the value
// when printing a pair
struct __has_defaulted_members {
static const bool value = !is_reference<first_type>::value && !is_reference<second_type>::value;
};
# if _LIBCPP_STD_VER >= 20
_LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(const pair&)
requires __has_defaulted_members::value
= default;

_LIBCPP_HIDE_FROM_ABI constexpr pair& operator=(pair&&)
requires __has_defaulted_members::value
= default;
# elif __has_attribute(__enable_if__)
_LIBCPP_HIDE_FROM_ABI pair& operator=(const pair&)
__attribute__((__enable_if__(__has_defaulted_members::value, ""))) = default;

_LIBCPP_HIDE_FROM_ABI pair& operator=(pair&&)
__attribute__((__enable_if__(__has_defaulted_members::value, ""))) = default;
# else
# error "_LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR isn't supported with this compiler"
# endif
#else
struct __has_defaulted_members {
static const bool value = false;
};
#endif // defined(_LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR) && __has_attribute(__enable_if__)

#ifdef _LIBCPP_CXX03_LANG
_LIBCPP_HIDE_FROM_ABI pair() : first(), second() {}

Expand Down Expand Up @@ -258,8 +225,7 @@ struct _LIBCPP_TEMPLATE_VIS pair
typename __make_tuple_indices<sizeof...(_Args2) >::type()) {}

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair&
operator=(__conditional_t<!__has_defaulted_members::value && is_copy_assignable<first_type>::value &&
is_copy_assignable<second_type>::value,
operator=(__conditional_t<is_copy_assignable<first_type>::value && is_copy_assignable<second_type>::value,
pair,
__nat> const& __p) noexcept(is_nothrow_copy_assignable<first_type>::value &&
is_nothrow_copy_assignable<second_type>::value) {
Expand All @@ -268,12 +234,10 @@ struct _LIBCPP_TEMPLATE_VIS pair
return *this;
}

_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair&
operator=(__conditional_t<!__has_defaulted_members::value && is_move_assignable<first_type>::value &&
is_move_assignable<second_type>::value,
pair,
__nat>&& __p) noexcept(is_nothrow_move_assignable<first_type>::value &&
is_nothrow_move_assignable<second_type>::value) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair& operator=(
__conditional_t<is_move_assignable<first_type>::value && is_move_assignable<second_type>::value, pair, __nat>&&
__p) noexcept(is_nothrow_move_assignable<first_type>::value &&
is_nothrow_move_assignable<second_type>::value) {
first = std::forward<first_type>(__p.first);
second = std::forward<second_type>(__p.second);
return *this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,8 @@ void test_trivial()
static_assert(!std::is_trivially_copy_constructible<P>::value, "");
static_assert(!std::is_trivially_move_constructible<P>::value, "");
#endif // TEST_STD_VER >= 11
#ifndef _LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR
static_assert(!std::is_trivially_copy_assignable<P>::value, "");
static_assert(!std::is_trivially_move_assignable<P>::value, "");
#else
static_assert(std::is_trivially_copy_assignable<P>::value, "");
static_assert(std::is_trivially_move_assignable<P>::value, "");
#endif
static_assert(std::is_trivially_destructible<P>::value, "");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,42 +47,22 @@ static_assert(!std::is_trivially_copyable<std::pair<int&, int> >::value, "");
static_assert(!std::is_trivially_copyable<std::pair<int, int&> >::value, "");
static_assert(!std::is_trivially_copyable<std::pair<int&, int&> >::value, "");

#ifdef _LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR
static_assert(std::is_trivially_copyable<std::pair<int, int> >::value, "");
static_assert(std::is_trivially_copyable<std::pair<int, char> >::value, "");
static_assert(std::is_trivially_copyable<std::pair<char, int> >::value, "");
static_assert(std::is_trivially_copyable<std::pair<std::pair<char, char>, int> >::value, "");
static_assert(std::is_trivially_copyable<std::pair<trivially_copyable, int> >::value, "");
#else
static_assert(!std::is_trivially_copyable<std::pair<int, int> >::value, "");
static_assert(!std::is_trivially_copyable<std::pair<int, char> >::value, "");
static_assert(!std::is_trivially_copyable<std::pair<char, int> >::value, "");
static_assert(!std::is_trivially_copyable<std::pair<std::pair<char, char>, int> >::value, "");
static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable, int> >::value, "");
#endif // _LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR

#if TEST_STD_VER == 03 // Known ABI difference
static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable_no_copy_assignment, int> >::value, "");
static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable_no_move_assignment, int> >::value, "");
#else
static_assert(std::is_trivially_copyable<std::pair<trivially_copyable_no_copy_assignment, int> >::value, "");
static_assert(std::is_trivially_copyable<std::pair<trivially_copyable_no_move_assignment, int> >::value, "");
#endif

#ifdef _LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR
static_assert(std::is_trivially_copyable<std::pair<trivially_copyable_no_construction, int> >::value, "");
#else
static_assert(!std::is_trivially_copyable<std::pair<trivially_copyable_no_construction, int> >::value, "");
#endif

static_assert(std::is_trivially_copy_constructible<std::pair<int, int> >::value, "");
static_assert(std::is_trivially_move_constructible<std::pair<int, int> >::value, "");
static_assert(std::is_trivially_destructible<std::pair<int, int> >::value, "");

#ifdef _LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR
static_assert(std::is_trivially_copy_assignable<std::pair<int, int> >::value, "");
static_assert(std::is_trivially_move_assignable<std::pair<int, int> >::value, "");
#else
static_assert(!std::is_trivially_copy_assignable<std::pair<int, int> >::value, "");
static_assert(!std::is_trivially_move_assignable<std::pair<int, int> >::value, "");
#endif // _LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR
static_assert(std::is_trivially_destructible<std::pair<int, int> >::value, "");
Loading