This patch implements built-in trait for std::is_void. gcc/cp/ChangeLog:
* cp-trait.def: Define __is_void. * constraint.cc (diagnose_trait_expr): Handle CPTK_IS_VOID. * semantics.cc (trait_expr_value): Likewise. (finish_trait_expr): Likewise. gcc/testsuite/ChangeLog: * g++.dg/ext/has-builtin-1.C: Test existence of __is_void. * g++.dg/ext/is_void.C: New test. Signed-off-by: Ken Matsui <kmat...@cs.washington.edu> --- gcc/cp/constraint.cc | 3 ++ gcc/cp/cp-trait.def | 1 + gcc/cp/semantics.cc | 4 +++ gcc/testsuite/g++.dg/ext/has-builtin-1.C | 3 ++ gcc/testsuite/g++.dg/ext/is_void.C | 35 ++++++++++++++++++++++++ 5 files changed, 46 insertions(+) create mode 100644 gcc/testsuite/g++.dg/ext/is_void.C diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 500ac9177c7..e67c0ffeaac 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3753,6 +3753,9 @@ diagnose_trait_expr (tree expr, tree args) case CPTK_IS_FUNCTION: inform (loc, " %qT is not a function", t1); break; + case CPTK_IS_VOID: + inform (loc, " %qT is not a void type", t1); + break; case CPTK_IS_AGGREGATE: inform (loc, " %qT is not an aggregate", t1); break; diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def index 99195201676..6284924630a 100644 --- a/gcc/cp/cp-trait.def +++ b/gcc/cp/cp-trait.def @@ -84,6 +84,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_CONSTRUCTIBLE, "__is_trivially_constructible", -1) DEFTRAIT_EXPR (IS_TRIVIALLY_COPYABLE, "__is_trivially_copyable", 1) DEFTRAIT_EXPR (IS_UNION, "__is_union", 1) DEFTRAIT_EXPR (IS_FUNCTION, "__is_function", 1) +DEFTRAIT_EXPR (IS_VOID, "__is_void", 1) DEFTRAIT_EXPR (REF_CONSTRUCTS_FROM_TEMPORARY, "__reference_constructs_from_temporary", 2) DEFTRAIT_EXPR (REF_CONVERTS_FROM_TEMPORARY, "__reference_converts_from_temporary", 2) /* FIXME Added space to avoid direct usage in GCC 13. */ diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 36fe370da2d..a6598fedfbc 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -11996,6 +11996,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_FUNCTION: return type_code1 == FUNCTION_TYPE; + case CPTK_IS_VOID: + return VOID_TYPE_P (type1); + case CPTK_IS_FINAL: return CLASS_TYPE_P (type1) && CLASSTYPE_FINAL (type1); @@ -12209,6 +12212,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_SAME: case CPTK_IS_REFERENCE: case CPTK_IS_FUNCTION: + case CPTK_IS_VOID: break; case CPTK_IS_LAYOUT_COMPATIBLE: diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C index 90eb00ebf2d..b96cc9e6f50 100644 --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C @@ -152,3 +152,6 @@ #if !__has_builtin (__is_function) # error "__has_builtin (__is_function) failed" #endif +#if !__has_builtin (__is_void) +# error "__has_builtin (__is_void) failed" +#endif diff --git a/gcc/testsuite/g++.dg/ext/is_void.C b/gcc/testsuite/g++.dg/ext/is_void.C new file mode 100644 index 00000000000..707f0d6875b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_void.C @@ -0,0 +1,35 @@ +// { dg-do compile { target c++11 } } + +#include <testsuite_tr1.h> + +using namespace __gnu_test; + +#define SA(X) static_assert((X),#X) +#define SA_TEST_CATEGORY(TRAIT, TYPE, EXPECT) \ + SA(TRAIT(TYPE) == EXPECT); \ + SA(TRAIT(const TYPE) == EXPECT); \ + SA(TRAIT(volatile TYPE) == EXPECT); \ + SA(TRAIT(const volatile TYPE) == EXPECT) + +SA_TEST_CATEGORY(__is_void, void, true); + +SA_TEST_CATEGORY(__is_void, char, false); +SA_TEST_CATEGORY(__is_void, signed char, false); +SA_TEST_CATEGORY(__is_void, unsigned char, false); +SA_TEST_CATEGORY(__is_void, wchar_t, false); +SA_TEST_CATEGORY(__is_void, short, false); +SA_TEST_CATEGORY(__is_void, unsigned short, false); +SA_TEST_CATEGORY(__is_void, int, false); +SA_TEST_CATEGORY(__is_void, unsigned int, false); +SA_TEST_CATEGORY(__is_void, long, false); +SA_TEST_CATEGORY(__is_void, unsigned long, false); +SA_TEST_CATEGORY(__is_void, long long, false); +SA_TEST_CATEGORY(__is_void, unsigned long long, false); +SA_TEST_CATEGORY(__is_void, float, false); +SA_TEST_CATEGORY(__is_void, double, false); +SA_TEST_CATEGORY(__is_void, long double, false); + +// Sanity check. +SA_TEST_CATEGORY(__is_void, ClassType, false); +SA_TEST_CATEGORY(__is_void, IncompleteClass, false); +SA_TEST_CATEGORY(__is_void, IncompleteUnion, false); -- 2.40.0