diff --git a/libcxx/include/__memory/compressed_pair.h b/libcxx/include/__memory/compressed_pair.h index 38798a21fa3c9..fb7b7b7afcc8c 100644 --- a/libcxx/include/__memory/compressed_pair.h +++ b/libcxx/include/__memory/compressed_pair.h @@ -15,7 +15,6 @@ #include <__type_traits/datasizeof.h> #include <__type_traits/is_empty.h> #include <__type_traits/is_final.h> -#include <__type_traits/is_reference.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -63,9 +62,17 @@ inline const size_t __compressed_pair_alignment = _LIBCPP_ALIGNOF(_Tp); template inline const size_t __compressed_pair_alignment<_Tp&> = _LIBCPP_ALIGNOF(void*); -template ::value && !__libcpp_is_final<_ToPad>::value) || - is_reference<_ToPad>::value || sizeof(_ToPad) == __datasizeof_v<_ToPad>)> +template +inline const bool __is_reference_or_unpadded_object = + (is_empty<_ToPad>::value && !__libcpp_is_final<_ToPad>::value) || sizeof(_ToPad) == __datasizeof_v<_ToPad>; + +template +inline const bool __is_reference_or_unpadded_object<_Tp&> = true; + +template +inline const bool __is_reference_or_unpadded_object<_Tp&&> = true; + +template > class __compressed_pair_padding { char __padding_[sizeof(_ToPad) - __datasizeof_v<_ToPad>] = {}; }; diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp index a91abc856fb19..a438bfb58ce44 100644 --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp @@ -32,6 +32,8 @@ bool my_free_called = false; void my_free(void*) { my_free_called = true; } +TEST_CONSTEXPR_CXX23 void deleter_function(A*) {} + #if TEST_STD_VER >= 11 struct DeleterBase { TEST_CONSTEXPR_CXX23 void operator()(void*) const {} @@ -325,6 +327,21 @@ TEST_CONSTEXPR_CXX23 void test_nullptr() { #endif } +template +TEST_CONSTEXPR_CXX23 void test_function_reference() { + typedef typename std::conditional::type VT; + { + std::unique_ptr u(nullptr, deleter_function); + assert(u.get() == nullptr); + assert(u.get_deleter() == deleter_function); + } + { + std::unique_ptr u(nullptr, deleter_function); + assert(u.get() == nullptr); + assert(u.get_deleter() == deleter_function); + } +} + TEST_CONSTEXPR_CXX23 bool test() { { test_basic(); @@ -332,6 +349,7 @@ TEST_CONSTEXPR_CXX23 bool test() { test_basic_single(); test_sfinae(); test_noexcept(); + test_function_reference(); } { test_basic(); @@ -339,6 +357,7 @@ TEST_CONSTEXPR_CXX23 bool test() { test_sfinae(); test_sfinae_runtime(); test_noexcept(); + test_function_reference(); } return true;