Index: libcxx/include/__memory/unique_ptr.h =================================================================== --- libcxx/include/__memory/unique_ptr.h +++ libcxx/include/__memory/unique_ptr.h @@ -47,10 +47,8 @@ 0) _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT { - static_assert(sizeof(_Tp) > 0, - "default_delete can not delete incomplete type"); - static_assert(!is_void<_Tp>::value, - "default_delete can not delete incomplete type"); + static_assert(sizeof(_Tp) >= 0, "cannot delete an incomplete type"); + static_assert(!is_void<_Tp>::value, "cannot delete an incomplete type"); delete __ptr; } }; @@ -78,10 +76,7 @@ _LIBCPP_INLINE_VISIBILITY typename _EnableIfConvertible<_Up>::type operator()(_Up* __ptr) const _NOEXCEPT { - static_assert(sizeof(_Tp) > 0, - "default_delete can not delete incomplete type"); - static_assert(!is_void<_Tp>::value, - "default_delete can not delete void type"); + static_assert(sizeof(_Up) >= 0, "cannot delete an incomplete type"); delete[] __ptr; } }; Index: libcxx/include/__ranges/access.h =================================================================== --- libcxx/include/__ranges/access.h +++ libcxx/include/__ranges/access.h @@ -59,14 +59,14 @@ struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[]) const noexcept - requires (sizeof(_Tp) != 0) // Disallow incomplete element types. + requires (sizeof(_Tp) >= 0) // Disallow incomplete element types. { return __t + 0; } template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept - requires (sizeof(_Tp) != 0) // Disallow incomplete element types. + requires (sizeof(_Tp) >= 0) // Disallow incomplete element types. { return __t + 0; } @@ -133,7 +133,7 @@ public: template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept - requires (sizeof(_Tp) != 0) // Disallow incomplete element types. + requires (sizeof(_Tp) >= 0) // Disallow incomplete element types. { return __t + _Np; } Index: libcxx/test/std/ranges/range.access/begin.sizezero.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/ranges/range.access/begin.sizezero.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: msvc + +// std::ranges::begin +// std::ranges::cbegin +// Test the fix for https://llvm.org/PR54100 + +#include +#include + +#include "test_macros.h" + +struct A { + int m[0]; +}; +static_assert(sizeof(A) == 0); // an extension supported by GCC and Clang + +int main(int, char**) +{ + A a[10]; + std::same_as auto p = std::ranges::begin(a); + assert(p == a); + std::same_as auto cp = std::ranges::cbegin(a); + assert(cp == a); + + return 0; +} Index: libcxx/test/std/ranges/range.access/end.sizezero.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/ranges/range.access/end.sizezero.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: msvc + +// std::ranges::end +// std::ranges::cend +// Test the fix for https://llvm.org/PR54100 + +#include +#include + +#include "test_macros.h" + +struct A { + int m[0]; +}; +static_assert(sizeof(A) == 0); // an extension supported by GCC and Clang + +int main(int, char**) +{ + A a[10]; + std::same_as auto p = std::ranges::end(a); + assert(p == a + 10); + std::same_as auto cp = std::ranges::cend(a); + assert(cp == a + 10); + + return 0; +} Index: libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp =================================================================== --- /dev/null +++ libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.create/make_unique.sizezero.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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 code triggers https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104568 +// UNSUPPORTED: gcc-11 +// UNSUPPORTED: msvc + +// Test the fix for https://llvm.org/PR54100 + +#include +#include + +#include "test_macros.h" + +struct A { + int m[0]; +}; +static_assert(sizeof(A) == 0, ""); // an extension supported by GCC and Clang + +int main(int, char**) +{ + { + std::unique_ptr p = std::unique_ptr(new A); + assert(p != nullptr); + } + { + std::unique_ptr p = std::unique_ptr(new A[1]); + assert(p != nullptr); + } +#if TEST_STD_VER > 11 + { + std::unique_ptr p = std::make_unique(); + assert(p != nullptr); + } + { + std::unique_ptr p = std::make_unique(1); + assert(p != nullptr); + } +#endif + return 0; +}