diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index c909a4300db1a..05b08da521535 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -336,6 +336,8 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_ios_noreplace`` ``202207L`` ---------------------------------------------------------- ----------------- + ``__cpp_lib_is_implicit_lifetime`` ``202302L`` + ---------------------------------------------------------- ----------------- ``__cpp_lib_is_scoped_enum`` ``202011L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_mdspan`` ``202207L`` diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst index 82c8286b69e23..dcb1102d81d64 100644 --- a/libcxx/docs/ReleaseNotes/20.rst +++ b/libcxx/docs/ReleaseNotes/20.rst @@ -42,6 +42,7 @@ Implemented Papers - P2609R3: Relaxing Ranges Just A Smidge (`Github `__) - P2985R0: A type trait for detecting virtual base classes (`Github `__) - ``std::jthread`` and ```` are not guarded behind ``-fexperimental-library`` anymore +- P2674R1: A trait for implicit lifetime types (`Github `__) Improvements and New Features ----------------------------- diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv index e1d7bb8f37863..da7b588187713 100644 --- a/libcxx/docs/Status/Cxx23Papers.csv +++ b/libcxx/docs/Status/Cxx23Papers.csv @@ -113,7 +113,7 @@ "`P2572R1 `__","``std::format`` fill character allowances","2023-02 (Issaquah)","|Complete|","17.0","" "`P2693R1 `__","Formatting ``thread::id`` and ``stacktrace``","2023-02 (Issaquah)","|Partial|","","The formatter for ``stacktrace`` is not implemented, since ``stacktrace`` is not implemented yet" "`P2679R2 `__","Fixing ``std::start_lifetime_as`` for arrays","2023-02 (Issaquah)","","","" -"`P2674R1 `__","A trait for implicit lifetime types","2023-02 (Issaquah)","","","" +"`P2674R1 `__","A trait for implicit lifetime types","2023-02 (Issaquah)","|Complete|","20.0","" "`P2655R3 `__","``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type","2023-02 (Issaquah)","","","" "`P2652R2 `__","Disallow User Specialization of ``allocator_traits``","2023-02 (Issaquah)","|Complete|","19.0","" "`P2787R1 `__","``pmr::generator`` - Promise Types are not Values","2023-02 (Issaquah)","","","" diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 9bd1b41b8bfac..c2a597f49e317 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -787,6 +787,7 @@ set(files __type_traits/is_floating_point.h __type_traits/is_function.h __type_traits/is_fundamental.h + __type_traits/is_implicit_lifetime.h __type_traits/is_implicitly_default_constructible.h __type_traits/is_integral.h __type_traits/is_literal_type.h diff --git a/libcxx/include/__type_traits/is_implicit_lifetime.h b/libcxx/include/__type_traits/is_implicit_lifetime.h new file mode 100644 index 0000000000000..2aba420bd2b59 --- /dev/null +++ b/libcxx/include/__type_traits/is_implicit_lifetime.h @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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___TYPE_TRAITS_IS_IMPLICIT_LIFETIME_H +#define _LIBCPP___TYPE_TRAITS_IS_IMPLICIT_LIFETIME_H + +#include <__config> +#include <__type_traits/integral_constant.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 23 +# if __has_builtin(__builtin_is_implicit_lifetime) + +template +struct _LIBCPP_TEMPLATE_VIS is_implicit_lifetime : public bool_constant<__builtin_is_implicit_lifetime(_Tp)> {}; + +template +inline constexpr bool is_implicit_lifetime_v = __builtin_is_implicit_lifetime(_Tp); + +# endif +#endif + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___TYPE_TRAITS_IS_IMPLICIT_LIFETIME_H diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap index dee9b0b88b794..22a1313498e73 100644 --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -200,6 +200,10 @@ module std_core [system] { header "__type_traits/is_fundamental.h" export std_core.type_traits.integral_constant } + module is_implicit_lifetime { + header "__type_traits/is_implicit_lifetime.h" + export std_core.type_traits.integral_constant + } module is_implicitly_default_constructible { header "__type_traits/is_implicitly_default_constructible.h" export std_core.type_traits.integral_constant diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index 26c85f2284e2f..baeed35ca8508 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -137,6 +137,8 @@ namespace std template struct is_nothrow_swappable; // C++17 template struct is_nothrow_destructible; + template struct is_implicit_lifetime; // Since C++23 + template struct has_virtual_destructor; template struct has_unique_object_representations; // C++17 @@ -374,6 +376,8 @@ namespace std = is_nothrow_swappable::value; // C++17 template inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible::value; // C++17 + template + constexpr bool is_implicit_lifetime_v = is_implicit_lifetime::value; // Since C++23 template inline constexpr bool has_virtual_destructor_v = has_virtual_destructor::value; // C++17 template inline constexpr bool has_unique_object_representations_v // C++17 @@ -516,6 +520,10 @@ namespace std # include <__type_traits/unwrap_ref.h> #endif +#if _LIBCPP_STD_VER >= 23 +# include <__type_traits/is_implicit_lifetime.h> +#endif + #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/version b/libcxx/include/version index 5d679caac0b3b..88387e311636c 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -138,6 +138,7 @@ __cpp_lib_ios_noreplace 202207L __cpp_lib_is_aggregate 201703L __cpp_lib_is_constant_evaluated 201811L __cpp_lib_is_final 201402L +__cpp_lib_is_implicit_lifetime 202302L __cpp_lib_is_invocable 201703L __cpp_lib_is_layout_compatible 201907L __cpp_lib_is_nothrow_convertible 201806L @@ -473,6 +474,9 @@ __cpp_lib_void_t 201411L # define __cpp_lib_forward_like 202207L # define __cpp_lib_invoke_r 202106L # define __cpp_lib_ios_noreplace 202207L +# if __has_builtin(__builtin_is_implicit_lifetime) +# define __cpp_lib_is_implicit_lifetime 202302L +# endif # define __cpp_lib_is_scoped_enum 202011L # define __cpp_lib_mdspan 202207L # define __cpp_lib_modules 202207L diff --git a/libcxx/modules/std/type_traits.inc b/libcxx/modules/std/type_traits.inc index 485a5ddf63aed..f544f95c7aaaa 100644 --- a/libcxx/modules/std/type_traits.inc +++ b/libcxx/modules/std/type_traits.inc @@ -98,7 +98,9 @@ export namespace std { using std::is_nothrow_destructible; - // using std::is_implicit_lifetime; +#if _LIBCPP_STD_VER >= 23 && __has_builtin(__builtin_is_implicit_lifetime) + using std::is_implicit_lifetime; +#endif using std::has_virtual_destructor; @@ -246,7 +248,9 @@ export namespace std { using std::is_destructible_v; using std::is_empty_v; using std::is_final_v; - // using std::is_implicit_lifetime_v; +#if _LIBCPP_STD_VER >= 23 && __has_builtin(__builtin_is_implicit_lifetime) + using std::is_implicit_lifetime_v; +#endif using std::is_move_assignable_v; using std::is_move_constructible_v; using std::is_nothrow_assignable_v; diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.compile.pass.cpp index 1cbf2699a95bc..d9d698ace2b65 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.compile.pass.cpp @@ -23,6 +23,7 @@ __cpp_lib_is_aggregate 201703L [C++17] __cpp_lib_is_constant_evaluated 201811L [C++20] __cpp_lib_is_final 201402L [C++14] + __cpp_lib_is_implicit_lifetime 202302L [C++23] __cpp_lib_is_invocable 201703L [C++17] __cpp_lib_is_layout_compatible 201907L [C++20] __cpp_lib_is_nothrow_convertible 201806L [C++20] @@ -75,6 +76,10 @@ # error "__cpp_lib_is_final should not be defined before c++14" # endif +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + # ifdef __cpp_lib_is_invocable # error "__cpp_lib_is_invocable should not be defined before c++17" # endif @@ -179,6 +184,10 @@ # error "__cpp_lib_is_final should have the value 201402L in c++14" # endif +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + # ifdef __cpp_lib_is_invocable # error "__cpp_lib_is_invocable should not be defined before c++17" # endif @@ -301,6 +310,10 @@ # error "__cpp_lib_is_final should have the value 201402L in c++17" # endif +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + # ifndef __cpp_lib_is_invocable # error "__cpp_lib_is_invocable should be defined in c++17" # endif @@ -444,6 +457,10 @@ # error "__cpp_lib_is_final should have the value 201402L in c++20" # endif +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + # ifndef __cpp_lib_is_invocable # error "__cpp_lib_is_invocable should be defined in c++20" # endif @@ -614,6 +631,19 @@ # error "__cpp_lib_is_final should have the value 201402L in c++23" # endif +# if __has_builtin(__builtin_is_implicit_lifetime) +# ifndef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should be defined in c++23" +# endif +# if __cpp_lib_is_implicit_lifetime != 202302L +# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++23" +# endif +# else +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!" +# endif +# endif + # ifndef __cpp_lib_is_invocable # error "__cpp_lib_is_invocable should be defined in c++23" # endif @@ -796,6 +826,19 @@ # error "__cpp_lib_is_final should have the value 201402L in c++26" # endif +# if __has_builtin(__builtin_is_implicit_lifetime) +# ifndef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should be defined in c++26" +# endif +# if __cpp_lib_is_implicit_lifetime != 202302L +# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++26" +# endif +# else +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!" +# endif +# endif + # ifndef __cpp_lib_is_invocable # error "__cpp_lib_is_invocable should be defined in c++26" # endif diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index 985ffeffab96d..0614f64a2ef04 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -125,6 +125,7 @@ __cpp_lib_is_aggregate 201703L [C++17] __cpp_lib_is_constant_evaluated 201811L [C++20] __cpp_lib_is_final 201402L [C++14] + __cpp_lib_is_implicit_lifetime 202302L [C++23] __cpp_lib_is_invocable 201703L [C++17] __cpp_lib_is_layout_compatible 201907L [C++20] __cpp_lib_is_nothrow_convertible 201806L [C++20] @@ -671,6 +672,10 @@ # error "__cpp_lib_is_final should not be defined before c++14" # endif +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + # ifdef __cpp_lib_is_invocable # error "__cpp_lib_is_invocable should not be defined before c++17" # endif @@ -1550,6 +1555,10 @@ # error "__cpp_lib_is_final should have the value 201402L in c++14" # endif +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + # ifdef __cpp_lib_is_invocable # error "__cpp_lib_is_invocable should not be defined before c++17" # endif @@ -2564,6 +2573,10 @@ # error "__cpp_lib_is_final should have the value 201402L in c++17" # endif +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + # ifndef __cpp_lib_is_invocable # error "__cpp_lib_is_invocable should be defined in c++17" # endif @@ -3842,6 +3855,10 @@ # error "__cpp_lib_is_final should have the value 201402L in c++20" # endif +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + # ifndef __cpp_lib_is_invocable # error "__cpp_lib_is_invocable should be defined in c++20" # endif @@ -5306,6 +5323,19 @@ # error "__cpp_lib_is_final should have the value 201402L in c++23" # endif +# if __has_builtin(__builtin_is_implicit_lifetime) +# ifndef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should be defined in c++23" +# endif +# if __cpp_lib_is_implicit_lifetime != 202302L +# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++23" +# endif +# else +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!" +# endif +# endif + # ifndef __cpp_lib_is_invocable # error "__cpp_lib_is_invocable should be defined in c++23" # endif @@ -7112,6 +7142,19 @@ # error "__cpp_lib_is_final should have the value 201402L in c++26" # endif +# if __has_builtin(__builtin_is_implicit_lifetime) +# ifndef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should be defined in c++26" +# endif +# if __cpp_lib_is_implicit_lifetime != 202302L +# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++26" +# endif +# else +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!" +# endif +# endif + # ifndef __cpp_lib_is_invocable # error "__cpp_lib_is_invocable should be defined in c++26" # endif diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp new file mode 100644 index 0000000000000..a6ab77158aae1 --- /dev/null +++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.pass.cpp @@ -0,0 +1,237 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// These compilers don't support __builtin_is_implicit_lifetime yet. +// UNSUPPORTED: clang-17, clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16 + +// + +// template struct is_implicit_lifetime; + +#include +#include +#include +#include +#include + +#include "test_macros.h" +#include "type_algorithms.h" + +enum Enum { EV }; +enum SignedEnum : signed int {}; +enum UnsignedEnum : unsigned int {}; + +enum class EnumClass { EV }; +enum class SignedEnumClass : signed int {}; +enum class UnsignedEnumClass : unsigned int {}; + +struct EmptyStruct {}; +struct IncompleteStruct; + +struct NoEligibleTrivialContructor { + NoEligibleTrivialContructor() {}; + NoEligibleTrivialContructor(const NoEligibleTrivialContructor&) {} + NoEligibleTrivialContructor(NoEligibleTrivialContructor&&) {} +}; + +struct OnlyDefaultConstructorIsTrivial { + OnlyDefaultConstructorIsTrivial() = default; + OnlyDefaultConstructorIsTrivial(const OnlyDefaultConstructorIsTrivial&) {} + OnlyDefaultConstructorIsTrivial(OnlyDefaultConstructorIsTrivial&&) {} +}; + +struct AllContstructorsAreTrivial { + AllContstructorsAreTrivial() = default; + AllContstructorsAreTrivial(const AllContstructorsAreTrivial&) = default; + AllContstructorsAreTrivial(AllContstructorsAreTrivial&&) = default; +}; + +struct InheritedNoEligibleTrivialConstructor : NoEligibleTrivialContructor { + using NoEligibleTrivialContructor::NoEligibleTrivialContructor; +}; + +struct InheritedOnlyDefaultConstructorIsTrivial : OnlyDefaultConstructorIsTrivial { + using OnlyDefaultConstructorIsTrivial::OnlyDefaultConstructorIsTrivial; +}; + +struct InheritedAllContstructorsAreTrivial : AllContstructorsAreTrivial { + using AllContstructorsAreTrivial::AllContstructorsAreTrivial; +}; + +struct UserDeclaredDestructor { + ~UserDeclaredDestructor() = default; +}; + +struct UserProvidedDestructor { + ~UserProvidedDestructor() {} +}; + +struct UserDeletedDestructorInAggregate { + ~UserDeletedDestructorInAggregate() = delete; +}; + +struct UserDeletedDestructorInNonAggregate { + virtual void NonAggregate(); + ~UserDeletedDestructorInNonAggregate() = delete; +}; + +struct DeletedDestructorViaBaseInAggregate : UserDeletedDestructorInAggregate {}; +struct DeletedDestructorViaBaseInNonAggregate : UserDeletedDestructorInNonAggregate {}; + +template +struct ConstrainedUserDeclaredDefaultConstructor { + ConstrainedUserDeclaredDefaultConstructor() + requires B + = default; + ConstrainedUserDeclaredDefaultConstructor(const ConstrainedUserDeclaredDefaultConstructor&) {} +}; + +template +struct ConstrainedUserProvidedDestructor { + ~ConstrainedUserProvidedDestructor() = default; + ~ConstrainedUserProvidedDestructor() + requires B + {} +}; + +struct StructWithFlexibleArrayMember { + int arr[]; +}; + +struct StructWithZeroSizedArray { + int arr[0]; +}; + +// Test implicit-lifetime type +template +constexpr void test_is_implicit_lifetime() { + assert(std::is_implicit_lifetime::value == Expected); + assert(std::is_implicit_lifetime_v == Expected); +} + +// Test pointer, reference, array, etc. types +template +constexpr void test_is_implicit_lifetime() { + test_is_implicit_lifetime(); + + // cv-qualified + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + + // Pointer types + test_is_implicit_lifetime(); + + // Arrays + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); +} + +struct AritmeticTypesTest { + template + constexpr void operator()() { + test_is_implicit_lifetime(); + } +}; + +constexpr bool test() { + // Standard fundamental C++ types + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + + types::for_each(types::arithmetic_types(), AritmeticTypesTest{}); + + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + + // Implicit-lifetime class types + + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); // Pointer-to-member + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime, true>(); + test_is_implicit_lifetime, false>(); + + test_is_implicit_lifetime, false>(); + test_is_implicit_lifetime, true>(); + + test_is_implicit_lifetime(); + + test_is_implicit_lifetime(); + + // C++ standard library types + + test_is_implicit_lifetime>(); + test_is_implicit_lifetime>(); + + // Standard C23 types + +#ifdef TEST_COMPILER_CLANG + test_is_implicit_lifetime<_BitInt(8)>(); + test_is_implicit_lifetime<_BitInt(128)>(); +#endif + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.verify.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.verify.cpp new file mode 100644 index 0000000000000..25bba30da612e --- /dev/null +++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_implicit_lifetime.verify.cpp @@ -0,0 +1,26 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// These compilers don't support __builtin_is_implicit_lifetime yet. +// UNSUPPORTED: clang-17, clang-18, clang-19, gcc-14, apple-clang-15, apple-clang-16 + +// + +// template struct is_implicit_lifetime; + +#include + +struct IncompleteStruct; + +// expected-error@*:* {{incomplete type 'IncompleteStruct' used in type trait expression}} +static_assert(!std::is_implicit_lifetime::value); + +// expected-error@*:* {{incomplete type 'IncompleteStruct' used in type trait expression}} +static_assert(!std::is_implicit_lifetime_v); diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index 3b8a52362ede6..db14c1781dc35 100755 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -742,6 +742,13 @@ def add_version_header(tc): "values": {"c++14": 201402}, "headers": ["type_traits"], }, + { + "name": "__cpp_lib_is_implicit_lifetime", + "values": {"c++23": 202302}, + "headers": ["type_traits"], + "test_suite_guard": "__has_builtin(__builtin_is_implicit_lifetime)", + "libcxx_guard": "__has_builtin(__builtin_is_implicit_lifetime)", + }, { "name": "__cpp_lib_is_invocable", "values": {"c++17": 201703},