diff options
Diffstat (limited to 'libcxx')
10 files changed, 103 insertions, 10 deletions
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index d900497eba7..4d3b0799ab5 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -188,7 +188,7 @@ Status ------------------------------------------------- ----------------- ``__cpp_lib_generic_unordered_lookup`` *unimplemented* ------------------------------------------------- ----------------- - ``__cpp_lib_is_constant_evaluated`` *unimplemented* + ``__cpp_lib_is_constant_evaluated`` ``201811L`` ------------------------------------------------- ----------------- ``__cpp_lib_list_remove_return_type`` *unimplemented* ------------------------------------------------- ----------------- diff --git a/libcxx/include/__config b/libcxx/include/__config index ead522520e8..0488093aa05 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1257,6 +1257,10 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #define _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF #endif +#if !__has_builtin(__builtin_is_constant_evaluated) && _GNUC_VER < 900 +#define _LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED +#endif + #if !defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) # if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION) # define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index 43faf275cff..65716295233 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -4876,6 +4876,13 @@ enum class endian }; #endif +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) +_LIBCPP_INLINE_VISIBILITY +inline constexpr bool is_constant_evaluated() noexcept { + return __builtin_is_constant_evaluated(); +} +#endif + _LIBCPP_END_NAMESPACE_STD #if _LIBCPP_STD_VER > 14 diff --git a/libcxx/include/version b/libcxx/include/version index 1037ee5df40..948f64512c9 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -222,7 +222,9 @@ __cpp_lib_void_t 201411L <type_traits> // # define __cpp_lib_destroying_delete 201806L # define __cpp_lib_erase_if 201811L // # define __cpp_lib_generic_unordered_lookup 201811L -// # define __cpp_lib_is_constant_evaluated 201811L +# if !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) +# define __cpp_lib_is_constant_evaluated 201811L +# endif // # define __cpp_lib_list_remove_return_type 201806L // # define __cpp_lib_ranges 201811L // # define __cpp_lib_three_way_comparison 201711L diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp index 7e8b3de35f4..29e76b36e4c 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/type_traits.version.pass.cpp @@ -315,16 +315,16 @@ # endif # endif -# if !defined(_LIBCPP_VERSION) +# if TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) || TEST_GCC_VER >= 900 # ifndef __cpp_lib_is_constant_evaluated # error "__cpp_lib_is_constant_evaluated should be defined in c++2a" # endif # if __cpp_lib_is_constant_evaluated != 201811L # error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++2a" # endif -# else // _LIBCPP_VERSION +# else # ifdef __cpp_lib_is_constant_evaluated -# error "__cpp_lib_is_constant_evaluated should not be defined because it is unimplemented in libc++!" +# error "__cpp_lib_is_constant_evaluated should not be defined when TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) || TEST_GCC_VER >= 900 is not defined!" # endif # endif diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp index b85d42d00ca..7735a13db30 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp @@ -1798,16 +1798,16 @@ # endif # endif -# if !defined(_LIBCPP_VERSION) +# if TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) || TEST_GCC_VER >= 900 # ifndef __cpp_lib_is_constant_evaluated # error "__cpp_lib_is_constant_evaluated should be defined in c++2a" # endif # if __cpp_lib_is_constant_evaluated != 201811L # error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++2a" # endif -# else // _LIBCPP_VERSION +# else # ifdef __cpp_lib_is_constant_evaluated -# error "__cpp_lib_is_constant_evaluated should not be defined because it is unimplemented in libc++!" +# error "__cpp_lib_is_constant_evaluated should not be defined when TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) || TEST_GCC_VER >= 900 is not defined!" # endif # endif diff --git a/libcxx/test/std/utilities/meta/meta.const.eval/is_constant_evaluated.fail.cpp b/libcxx/test/std/utilities/meta/meta.const.eval/is_constant_evaluated.fail.cpp new file mode 100644 index 00000000000..c139233b8da --- /dev/null +++ b/libcxx/test/std/utilities/meta/meta.const.eval/is_constant_evaluated.fail.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// 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++98, c++03 + +// <type_traits> + + +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +int main(int, char**) +{ +#ifndef __cpp_lib_is_constant_evaluated + // expected-error@+1 {{no member named 'is_constant_evaluated' in namespace 'std'}} + bool b = std::is_constant_evaluated(); +#else + // expected-error@+1 {{static_assert failed}} + static_assert(!std::is_constant_evaluated(), ""); +#endif + return 0; +} diff --git a/libcxx/test/std/utilities/meta/meta.const.eval/is_constant_evaluated.pass.cpp b/libcxx/test/std/utilities/meta/meta.const.eval/is_constant_evaluated.pass.cpp new file mode 100644 index 00000000000..4dc796e950f --- /dev/null +++ b/libcxx/test/std/utilities/meta/meta.const.eval/is_constant_evaluated.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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++98, c++03, c++11, c++14, c++17 + +// <type_traits> + +// constexpr bool is_constant_evaluated() noexcept; // C++20 + +#include <type_traits> +#include <cassert> + +#include "test_macros.h" + +#ifndef __cpp_lib_is_constant_evaluated +#if TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) +# error __cpp_lib_is_constant_evaluated should be defined +#endif +#endif + +template <bool> struct InTemplate {}; + +int main(int, char**) +{ +#ifdef __cpp_lib_is_constant_evaluated + // Test the signature + { + ASSERT_SAME_TYPE(decltype(std::is_constant_evaluated()), bool); + ASSERT_NOEXCEPT(std::is_constant_evaluated()); + constexpr bool p = std::is_constant_evaluated(); + assert(p); + } + // Test the return value of the builtin for basic sanity only. It's the + // compilers job to test tho builtin for correctness. + { + static_assert(std::is_constant_evaluated(), ""); + bool p = std::is_constant_evaluated(); + assert(!p); + ASSERT_SAME_TYPE(InTemplate<std::is_constant_evaluated()>, InTemplate<true>); + static int local_static = std::is_constant_evaluated() ? 42 : -1; + assert(local_static == 42); + } +#endif + return 0; +} diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index c11846ec6e1..ed015876aef 100755 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -525,7 +525,8 @@ feature_test_macros = sorted([ add_version_header(x) for x in [ "c++2a": 201811L, }, "headers": ["type_traits"], - "unimplemented": True, + "depends": "TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) || TEST_GCC_VER >= 900", + "internal_depends": "!defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED)", }, {"name": "__cpp_lib_list_remove_return_type", "values": { diff --git a/libcxx/www/cxx2a_status.html b/libcxx/www/cxx2a_status.html index 0adc0e18ed7..e6f5444977e 100644 --- a/libcxx/www/cxx2a_status.html +++ b/libcxx/www/cxx2a_status.html @@ -113,7 +113,7 @@ <tr><td><a href="https://wg21.link/P0482R6">P0482R6</a></td><td>CWG</td><td>char8_t: A type for UTF-8 characters and strings</td><td>San Diego</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P0487R1">P0487R1</a></td><td>LWG</td><td>Fixing operator>>(basic_istream&, CharT*) (LWG 2499)</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr> <tr><td><a href="https://wg21.link/P0591R4">P0591R4</a></td><td>LWG</td><td>Utility functions to implement uses-allocator construction</td><td>San Diego</td><td><i> </i></td><td></td></tr> - <tr><td><a href="https://wg21.link/P0595R2">P0595R2</a></td><td>CWG</td><td>P0595R2 std::is_constant_evaluated()</td><td>San Diego</td><td><i> </i></td><td></td></tr> + <tr><td><a href="https://wg21.link/P0595R2">P0595R2</a></td><td>CWG</td><td>P0595R2 std::is_constant_evaluated()</td><td>San Diego</td><td>Complete</td><td>9.0</td></tr> <tr><td><a href="https://wg21.link/P0602R4">P0602R4</a></td><td>LWG</td><td>variant and optional should propagate copy/move triviality</td><td>San Diego</td><td>Complete</td><td>8.0</td></tr> <tr><td><a href="https://wg21.link/P0608R3">P0608R3</a></td><td>LWG</td><td>A sane variant converting constructor</td><td>San Diego</td><td><i> </i></td><td></td></tr> <tr><td><a href="https://wg21.link/P0655R1">P0655R1</a></td><td>LWG</td><td>visit<R>: Explicit Return Type for visit</td><td>San Diego</td><td><i> </i></td><td></td></tr> |