Implement std::is_consteval_only{,_v} trait.

This commit is contained in:
Jakub Jelinek
2025-09-25 15:11:22 +02:00
committed by Marek Polacek
parent 0510df7079
commit 4838b479b0
7 changed files with 136 additions and 0 deletions

View File

@@ -3316,6 +3316,9 @@ diagnose_trait_expr (location_t loc, tree expr, tree args)
case CPTK_IS_VOLATILE:
inform (loc, "%qT is not a volatile type", t1);
break;
case CPTK_IS_CONSTEVAL_ONLY:
inform (decl_loc, "%qT is not consteval-only", t1);
break;
case CPTK_RANK:
inform (loc, "%qT cannot yield a rank", t1);
break;

View File

@@ -69,6 +69,7 @@ DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
DEFTRAIT_EXPR (IS_BOUNDED_ARRAY, "__is_bounded_array", 1)
DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
DEFTRAIT_EXPR (IS_CONST, "__is_const", 1)
DEFTRAIT_EXPR (IS_CONSTEVAL_ONLY, "__builtin_is_consteval_only", 1)
DEFTRAIT_EXPR (IS_CONSTRUCTIBLE, "__is_constructible", -1)
DEFTRAIT_EXPR (IS_CONVERTIBLE, "__is_convertible", 2)
DEFTRAIT_EXPR (IS_DESTRUCTIBLE, "__is_destructible", 1)

View File

@@ -13914,6 +13914,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_DEDUCIBLE:
return type_targs_deducible_from (type1, type2);
case CPTK_IS_CONSTEVAL_ONLY:
return consteval_only_p (type1);
/* __array_rank, __builtin_type_order and __builtin_structured_binding_size
are handled in finish_trait_expr. */
case CPTK_RANK:
@@ -14094,6 +14097,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_STD_LAYOUT:
case CPTK_IS_TRIVIAL:
case CPTK_IS_TRIVIALLY_COPYABLE:
case CPTK_IS_CONSTEVAL_ONLY:
case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
if (!check_trait_type (type1, /* kind = */ 2))
return error_mark_node;

View File

@@ -3889,6 +3889,24 @@ template<typename _Ret, typename _Fn, typename... _Args>
# endif
#endif
#if __cpp_impl_reflection >= 202500L \
&& _GLIBCXX_USE_BUILTIN_TRAIT(__builtin_is_consteval_only) // C++ >= 26
/// is_consteval_only - true if the type is consteval-only.
/// @since C++26
template<typename _Tp>
struct is_consteval_only
: bool_constant<__builtin_is_consteval_only(_Tp)>
{ };
/** is_consteval_only_v - true if the type is consteval-only.
* @ingroup variable_templates
* @since C++26
*/
template<typename _Tp>
inline constexpr bool is_consteval_only_v
= __builtin_is_consteval_only(_Tp);
#endif
/** * Remove references and cv-qualifiers.
* @since C++20
* @{

View File

@@ -0,0 +1,29 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Copyright (C) 2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// NB: This file is for testing type_traits with NO OTHER INCLUDES.
#include <type_traits>
namespace std
{
typedef short test_type;
template struct is_consteval_only<test_type>;
}

View File

@@ -0,0 +1,34 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Copyright (C) 2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
//
// NB: This file is for testing type_traits with NO OTHER INCLUDES.
#include <type_traits>
void test01()
{
// Check for required typedefs
typedef std::is_consteval_only<decltype (^^int)> test_type;
typedef test_type::value_type value_type;
typedef test_type::type type;
typedef test_type::type::value_type type_value_type;
typedef test_type::type::type type_type;
}

View File

@@ -0,0 +1,47 @@
// { dg-do compile { target c++26 } }
// { dg-additional-options "-freflection" }
// Copyright (C) 2025 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include <type_traits>
#include <testsuite_tr1.h>
void test01()
{
using std::is_consteval_only;
using namespace __gnu_test;
int v = 1;
struct S1 { decltype(^^long) a; };
union U2 { int a; decltype(^^test01) b; };
struct S3 { const decltype(^^__gnu_test) *c; };
struct S4 : public S3 {};
struct S5 { int a; long *b; };
static_assert(test_category<is_consteval_only, decltype(^^long)>(true), "");
static_assert(test_category<is_consteval_only, const decltype(^^test01)>(true), "");
static_assert(test_category<is_consteval_only, volatile decltype(^^__gnu_test)>(true), "");
static_assert(test_category<is_consteval_only, const volatile decltype(^^v)>(true), "");
static_assert(test_category<is_consteval_only, const S1>(true), "");
static_assert(test_category<is_consteval_only, U2>(true), "");
static_assert(test_category<is_consteval_only, S3>(true), "");
static_assert(test_category<is_consteval_only, S4>(true), "");
// Sanity check.
static_assert(test_category<is_consteval_only, int>(false), "");
static_assert(test_category<is_consteval_only, S5>(false), "");
}