On 01-10 (01:23), Ken Matsui wrote: > This patch implements built-in trait for std::is_scalar. > > gcc/cp/ChangeLog: > > * cp-trait.def: Define __is_scalar. > * constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SCALAR. > * semantics.cc (trait_expr_value): Likewise. > (finish_trait_expr): Likewise. > > gcc/testsuite/ChangeLog: > > * g++.dg/ext/has-builtin-1.C: Test existence of __is_scalar. > * g++.dg/ext/is_scalar.C: New test. > > Signed-off-by: Ken Matsui <kmat...@gcc.gnu.org> > --- > gcc/cp/constraint.cc | 3 +++ > gcc/cp/cp-trait.def | 1 + > gcc/cp/semantics.cc | 10 +++++++++ > gcc/testsuite/g++.dg/ext/has-builtin-1.C | 3 +++ > gcc/testsuite/g++.dg/ext/is_scalar.C | 28 ++++++++++++++++++++++++ > 5 files changed, 45 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/ext/is_scalar.C > > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc > index d2e41aa053d..7293f33c676 100644 > --- a/gcc/cp/constraint.cc > +++ b/gcc/cp/constraint.cc > @@ -3810,6 +3810,9 @@ diagnose_trait_expr (tree expr, tree args) > case CPTK_IS_SAME: > inform (loc, " %qT is not the same as %qT", t1, t2); > break; > + case CPTK_IS_SCALAR: > + inform (loc, " %qT is not a scalar type", t1); > + break; > case CPTK_IS_SCOPED_ENUM: > inform (loc, " %qT is not a scoped enum", t1); > break; > diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def > index 6dac7622a7c..48e195b4938 100644 > --- a/gcc/cp/cp-trait.def > +++ b/gcc/cp/cp-trait.def > @@ -87,6 +87,7 @@ DEFTRAIT_EXPR (IS_POD, "__is_pod", 1) > DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1) > DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1) > DEFTRAIT_EXPR (IS_SAME, "__is_same", 2) > +DEFTRAIT_EXPR (IS_SCALAR, "__is_scalar", 1) > DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1) > DEFTRAIT_EXPR (IS_SIGNED, "__is_signed", 1) > DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1) > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc > index c3d6fc2d10f..2426ba629d9 100644 > --- a/gcc/cp/semantics.cc > +++ b/gcc/cp/semantics.cc > @@ -12545,6 +12545,15 @@ trait_expr_value (cp_trait_kind kind, tree type1, > tree type2) > case CPTK_IS_SAME: > return same_type_p (type1, type2); > > + case CPTK_IS_SCALAR: > + return (TYPE_PTRDATAMEM_P (type1) > + || TREE_CODE (type1) == ENUMERAL_TYPE > + || integral_type_p (type1) > + || floating_point_type_p (type1) > + || TYPE_PTR_P (type1) > + || TYPE_PTRMEMFUNC_P (type1) > + || NULLPTR_TYPE_P (type1)); > +
Hi Jonathan, Related to this Bugzilla report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96710 do we want to update the is_scalar behavior? For this patch, I just followed the current implementation. > case CPTK_IS_SCOPED_ENUM: > return SCOPED_ENUM_P (type1); > > @@ -12744,6 +12753,7 @@ finish_trait_expr (location_t loc, cp_trait_kind > kind, tree type1, tree type2) > case CPTK_IS_OBJECT: > case CPTK_IS_REFERENCE: > case CPTK_IS_SAME: > + case CPTK_IS_SCALAR: > case CPTK_IS_SCOPED_ENUM: > case CPTK_IS_SIGNED: > case CPTK_IS_UNION: > diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C > b/gcc/testsuite/g++.dg/ext/has-builtin-1.C > index e3d16add403..c860f7e12ca 100644 > --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C > +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C > @@ -143,6 +143,9 @@ > #if !__has_builtin (__is_same_as) > # error "__has_builtin (__is_same_as) failed" > #endif > +#if !__has_builtin (__is_scalar) > +# error "__has_builtin (__is_scalar) failed" > +#endif > #if !__has_builtin (__is_scoped_enum) > # error "__has_builtin (__is_scoped_enum) failed" > #endif > diff --git a/gcc/testsuite/g++.dg/ext/is_scalar.C > b/gcc/testsuite/g++.dg/ext/is_scalar.C > new file mode 100644 > index 00000000000..ad4c2d7ea05 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/ext/is_scalar.C > @@ -0,0 +1,28 @@ > +// { dg-do compile { target c++11 } } > + > +#define SA(X) static_assert((X),#X) > + > +#define SA_TEST_FN(TRAIT, TYPE, EXPECT) \ > + SA(TRAIT(TYPE) == EXPECT); \ > + SA(TRAIT(const TYPE) == EXPECT) > + > +#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) > + > +class ClassType { }; > +enum EnumType { e0 }; > + > +SA_TEST_CATEGORY(__is_scalar, int, true); > +SA_TEST_CATEGORY(__is_scalar, float, true); > +SA_TEST_CATEGORY(__is_scalar, EnumType, true); > +SA_TEST_CATEGORY(__is_scalar, int*, true); > +SA_TEST_FN(__is_scalar, int(*)(int), true); > +SA_TEST_CATEGORY(__is_scalar, int (ClassType::*), true); > +SA_TEST_FN(__is_scalar, int (ClassType::*) (int), true); > +SA_TEST_CATEGORY(__is_scalar, decltype(nullptr), true); > + > +// Sanity check. > +SA_TEST_CATEGORY(__is_scalar, ClassType, false); > -- > 2.43.0 >