mirror of
https://github.com/llvm-mirror/libcxx.git
synced 2025-10-23 01:18:52 +08:00
Add std::is_constant_evaluated.
Clang recently added __builtin_is_constant_evaluated() and GCC 9.0 has it as well. This patch adds support for it in libc++. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@359119 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -188,7 +188,7 @@ Status
|
|||||||
------------------------------------------------- -----------------
|
------------------------------------------------- -----------------
|
||||||
``__cpp_lib_generic_unordered_lookup`` *unimplemented*
|
``__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*
|
``__cpp_lib_list_remove_return_type`` *unimplemented*
|
||||||
------------------------------------------------- -----------------
|
------------------------------------------------- -----------------
|
||||||
|
@@ -1257,6 +1257,10 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
|
|||||||
#define _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
|
#define _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF
|
||||||
#endif
|
#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_HAS_NO_OFF_T_FUNCTIONS)
|
||||||
# if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION)
|
# if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION)
|
||||||
# define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
|
# define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS
|
||||||
|
@@ -4876,6 +4876,13 @@ enum class endian
|
|||||||
};
|
};
|
||||||
#endif
|
#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
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#if _LIBCPP_STD_VER > 14
|
#if _LIBCPP_STD_VER > 14
|
||||||
|
@@ -222,7 +222,9 @@ __cpp_lib_void_t 201411L <type_traits>
|
|||||||
// # define __cpp_lib_destroying_delete 201806L
|
// # define __cpp_lib_destroying_delete 201806L
|
||||||
# define __cpp_lib_erase_if 201811L
|
# define __cpp_lib_erase_if 201811L
|
||||||
// # define __cpp_lib_generic_unordered_lookup 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_list_remove_return_type 201806L
|
||||||
// # define __cpp_lib_ranges 201811L
|
// # define __cpp_lib_ranges 201811L
|
||||||
// # define __cpp_lib_three_way_comparison 201711L
|
// # define __cpp_lib_three_way_comparison 201711L
|
||||||
|
@@ -315,16 +315,16 @@
|
|||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# if !defined(_LIBCPP_VERSION)
|
# if TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) || TEST_GCC_VER >= 900
|
||||||
# ifndef __cpp_lib_is_constant_evaluated
|
# ifndef __cpp_lib_is_constant_evaluated
|
||||||
# error "__cpp_lib_is_constant_evaluated should be defined in c++2a"
|
# error "__cpp_lib_is_constant_evaluated should be defined in c++2a"
|
||||||
# endif
|
# endif
|
||||||
# if __cpp_lib_is_constant_evaluated != 201811L
|
# if __cpp_lib_is_constant_evaluated != 201811L
|
||||||
# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++2a"
|
# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++2a"
|
||||||
# endif
|
# endif
|
||||||
# else // _LIBCPP_VERSION
|
# else
|
||||||
# ifdef __cpp_lib_is_constant_evaluated
|
# 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
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
@@ -1798,16 +1798,16 @@
|
|||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# if !defined(_LIBCPP_VERSION)
|
# if TEST_HAS_BUILTIN(__builtin_is_constant_evaluated) || TEST_GCC_VER >= 900
|
||||||
# ifndef __cpp_lib_is_constant_evaluated
|
# ifndef __cpp_lib_is_constant_evaluated
|
||||||
# error "__cpp_lib_is_constant_evaluated should be defined in c++2a"
|
# error "__cpp_lib_is_constant_evaluated should be defined in c++2a"
|
||||||
# endif
|
# endif
|
||||||
# if __cpp_lib_is_constant_evaluated != 201811L
|
# if __cpp_lib_is_constant_evaluated != 201811L
|
||||||
# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++2a"
|
# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++2a"
|
||||||
# endif
|
# endif
|
||||||
# else // _LIBCPP_VERSION
|
# else
|
||||||
# ifdef __cpp_lib_is_constant_evaluated
|
# 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
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
}
|
@@ -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;
|
||||||
|
}
|
@@ -525,7 +525,8 @@ feature_test_macros = sorted([ add_version_header(x) for x in [
|
|||||||
"c++2a": 201811L,
|
"c++2a": 201811L,
|
||||||
},
|
},
|
||||||
"headers": ["type_traits"],
|
"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",
|
{"name": "__cpp_lib_list_remove_return_type",
|
||||||
"values": {
|
"values": {
|
||||||
|
@@ -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/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/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/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/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/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>
|
<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>
|
||||||
|
Reference in New Issue
Block a user