diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -106,6 +106,7 @@ __concepts/class_or_enum.h __concepts/common_reference_with.h __concepts/common_with.h + __concepts/complete_object_type.h __concepts/constructible.h __concepts/convertible_to.h __concepts/copyable.h diff --git a/libcxx/include/__concepts/complete_object_type.h b/libcxx/include/__concepts/complete_object_type.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__concepts/complete_object_type.h @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___CONCEPTS_COMPLETE_OBJECT_TYPE_H +#define _LIBCPP___CONCEPTS_COMPLETE_OBJECT_TYPE_H + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template +concept __complete_object_type = requires { + sizeof(_Tp); +}; + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___CONCEPTS_COMPLETE_OBJECT_TYPE_H diff --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h --- a/libcxx/include/__iterator/concepts.h +++ b/libcxx/include/__iterator/concepts.h @@ -11,6 +11,7 @@ #define _LIBCPP___ITERATOR_CONCEPTS_H #include <__config> +#include <__concepts/complete_object_type.h> #include <__iterator/incrementable_traits.h> #include <__iterator/iter_move.h> #include <__iterator/iterator_traits.h> @@ -174,7 +175,7 @@ derived_from<_ITER_CONCEPT<_Ip>, contiguous_iterator_tag> && is_lvalue_reference_v> && same_as, remove_cvref_t>> && - (is_pointer_v<_Ip> || requires { sizeof(__pointer_traits_element_type<_Ip>); }) && + (is_pointer_v<_Ip> || __complete_object_type<__pointer_traits_element_type<_Ip>>) && requires(const _Ip& __i) { { _VSTD::to_address(__i) } -> same_as>>; }; diff --git a/libcxx/include/__ranges/access.h b/libcxx/include/__ranges/access.h --- a/libcxx/include/__ranges/access.h +++ b/libcxx/include/__ranges/access.h @@ -10,6 +10,7 @@ #define _LIBCPP___RANGES_ACCESS_H #include <__config> +#include <__concepts/complete_object_type.h> #include <__iterator/concepts.h> #include <__iterator/readable_traits.h> #include <__ranges/enable_borrowed_range.h> @@ -36,9 +37,6 @@ template concept __can_borrow = is_lvalue_reference_v<_Tp> || enable_borrowed_range >; - - template - concept __is_complete = requires { sizeof(_Tp); }; } // namespace ranges // [range.access.begin] @@ -66,7 +64,7 @@ template requires is_array_v> [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const noexcept { - constexpr bool __complete = __is_complete >; + constexpr bool __complete = __complete_object_type >; if constexpr (__complete) { // used to disable cryptic diagnostic return __t + 0; } @@ -131,7 +129,7 @@ public: template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept { - constexpr bool __complete = __is_complete >; + constexpr bool __complete = __complete_object_type >; if constexpr (__complete) { // used to disable cryptic diagnostic return __t + _Np; } diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -380,6 +380,7 @@ module class_or_enum { private header "__concepts/class_or_enum.h" } module common_reference_with { private header "__concepts/common_reference_with.h" } module common_with { private header "__concepts/common_with.h" } + module complete { private header "__concepts/complete.h" } module constructible { private header "__concepts/constructible.h" } module convertible_to { private header "__concepts/convertible_to.h" } module copyable { private header "__concepts/copyable.h" } diff --git a/libcxx/test/libcxx/diagnostics/detail.headers/concepts/complete.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/concepts/complete.module.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/diagnostics/detail.headers/concepts/complete.module.verify.cpp @@ -0,0 +1,16 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// REQUIRES: modules-build + +// WARNING: This test was generated by 'generate_private_header_tests.py' +// and should not be edited manually. + +// expected-error@*:* {{use of private header from outside its module: '___concepts/complete.h'}} +#include <___concepts/complete.h>