[libc++] Tweak how we check constraints on shared_ptr(nullptr_t) (#94996)
This avoids breaking code that should arguably be valid but technically isn't after enforcing the constraints on shared_ptr's constructors. A new LWG issue was filed to fix this in the Standard. This patch applies the expected resolution of this issue to avoid flip-flopping users whose code should always be considered valid. See #93071 for more context.
This commit is contained in:
@@ -404,7 +404,7 @@ struct __shared_ptr_deleter_ctor_reqs {
|
||||
};
|
||||
|
||||
template <class _Dp, class _Tp>
|
||||
using __shared_ptr_nullptr_deleter_ctor_reqs = _And<is_move_constructible<_Dp>, __well_formed_deleter<_Dp, nullptr_t> >;
|
||||
using __shared_ptr_nullptr_deleter_ctor_reqs = _And<is_move_constructible<_Dp>, __well_formed_deleter<_Dp, _Tp*> >;
|
||||
|
||||
#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
|
||||
# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
|
||||
|
||||
@@ -32,17 +32,16 @@ int A::count = 0;
|
||||
// LWG 3233. Broken requirements for shared_ptr converting constructors
|
||||
// https://cplusplus.github.io/LWG/issue3233
|
||||
static_assert( std::is_constructible<std::shared_ptr<int>, std::nullptr_t, test_deleter<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, bad_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, no_nullptr_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, bad_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, no_move_deleter>::value, "");
|
||||
|
||||
#if TEST_STD_VER >= 17
|
||||
static_assert( std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, test_deleter<int> >::value, "");
|
||||
static_assert(std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, test_deleter<int[]> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, bad_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, no_nullptr_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, no_move_deleter>::value, "");
|
||||
|
||||
static_assert( std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, test_deleter<int> >::value, "");
|
||||
static_assert(std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, test_deleter<int[5]> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, bad_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, no_nullptr_deleter>::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, no_move_deleter>::value, "");
|
||||
|
||||
@@ -33,17 +33,21 @@ int A::count = 0;
|
||||
// LWG 3233. Broken requirements for shared_ptr converting constructors
|
||||
// https://cplusplus.github.io/LWG/issue3233
|
||||
static_assert( std::is_constructible<std::shared_ptr<int>, std::nullptr_t, test_deleter<int>, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, bad_deleter, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, no_nullptr_deleter, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, bad_deleter, test_allocator<int> >::value,
|
||||
"");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int>, std::nullptr_t, no_move_deleter, test_allocator<int> >::value, "");
|
||||
|
||||
#if TEST_STD_VER >= 17
|
||||
static_assert( std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, test_deleter<int>, test_allocator<int> >::value, "");
|
||||
static_assert(
|
||||
std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, test_deleter<int[]>, test_allocator<int> >::value,
|
||||
"");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, bad_deleter, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, no_nullptr_deleter, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[]>, std::nullptr_t, no_move_deleter, test_allocator<int> >::value, "");
|
||||
|
||||
static_assert( std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, test_deleter<int>, test_allocator<int> >::value, "");
|
||||
static_assert(
|
||||
std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, test_deleter<int[5]>, test_allocator<int> >::value,
|
||||
"");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, bad_deleter, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, no_nullptr_deleter, test_allocator<int> >::value, "");
|
||||
static_assert(!std::is_constructible<std::shared_ptr<int[5]>, std::nullptr_t, no_move_deleter, test_allocator<int> >::value, "");
|
||||
|
||||
@@ -115,6 +115,14 @@ int main(int, char**)
|
||||
}
|
||||
#endif // TEST_STD_VER >= 11
|
||||
|
||||
#if TEST_STD_VER >= 14
|
||||
{
|
||||
// See https://github.com/llvm/llvm-project/pull/93071#issuecomment-2158494851
|
||||
auto deleter = [](auto pointer) { delete pointer; };
|
||||
std::shared_ptr<int> p(new int, deleter);
|
||||
}
|
||||
#endif
|
||||
|
||||
test_function_type();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -165,5 +165,13 @@ int main(int, char**)
|
||||
test_allocator<Derived[4]> >::value, "");
|
||||
}
|
||||
|
||||
#if TEST_STD_VER >= 14
|
||||
{
|
||||
// See https://github.com/llvm/llvm-project/pull/93071#issuecomment-2158494851
|
||||
auto deleter = [](auto pointer) { delete pointer; };
|
||||
std::shared_ptr<int> p(new int, deleter, std::allocator<int>());
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user