This patch implements built-in trait for std::is_signed. gcc/cp/ChangeLog:
* cp-trait.def: Define __is_signed. * constraint.cc (diagnose_trait_expr): Handle CPTK_IS_SIGNED. * semantics.cc (trait_expr_value): Likewise. (finish_trait_expr): Likewise. gcc/testsuite/ChangeLog: * g++.dg/ext/has-builtin-1.C: Test existence of __is_signed. * g++.dg/ext/is_signed.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 | 6 ++++ gcc/testsuite/g++.dg/ext/has-builtin-1.C | 3 ++ gcc/testsuite/g++.dg/ext/is_signed.C | 45 ++++++++++++++++++++++++ 5 files changed, 58 insertions(+) create mode 100644 gcc/testsuite/g++.dg/ext/is_signed.C diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 7e4b3cd38c4..d2e41aa053d 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -3813,6 +3813,9 @@ diagnose_trait_expr (tree expr, tree args) case CPTK_IS_SCOPED_ENUM: inform (loc, " %qT is not a scoped enum", t1); break; + case CPTK_IS_SIGNED: + inform (loc, " %qT is not a signed type", t1); + break; case CPTK_IS_STD_LAYOUT: inform (loc, " %qT is not an standard layout type", t1); break; diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def index 734522eb5ba..6dac7622a7c 100644 --- a/gcc/cp/cp-trait.def +++ b/gcc/cp/cp-trait.def @@ -88,6 +88,7 @@ DEFTRAIT_EXPR (IS_POLYMORPHIC, "__is_polymorphic", 1) DEFTRAIT_EXPR (IS_REFERENCE, "__is_reference", 1) DEFTRAIT_EXPR (IS_SAME, "__is_same", 2) 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) DEFTRAIT_EXPR (IS_TRIVIAL, "__is_trivial", 1) DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE, "__is_trivially_assignable", 2) diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 522db3f57e4..c3d6fc2d10f 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -12548,6 +12548,11 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_SCOPED_ENUM: return SCOPED_ENUM_P (type1); + case CPTK_IS_SIGNED: + return (integral_type_p (type1) + || floating_point_type_p (type1)) + && TYPE_SIGN (type1) == SIGNED; + case CPTK_IS_STD_LAYOUT: return std_layout_type_p (type1); @@ -12740,6 +12745,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) case CPTK_IS_REFERENCE: case CPTK_IS_SAME: case CPTK_IS_SCOPED_ENUM: + case CPTK_IS_SIGNED: case CPTK_IS_UNION: case CPTK_IS_UNSIGNED: break; diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C index 062b06234e6..e3d16add403 100644 --- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C +++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C @@ -146,6 +146,9 @@ #if !__has_builtin (__is_scoped_enum) # error "__has_builtin (__is_scoped_enum) failed" #endif +#if !__has_builtin (__is_signed) +# error "__has_builtin (__is_signed) failed" +#endif #if !__has_builtin (__is_standard_layout) # error "__has_builtin (__is_standard_layout) failed" #endif diff --git a/gcc/testsuite/g++.dg/ext/is_signed.C b/gcc/testsuite/g++.dg/ext/is_signed.C new file mode 100644 index 00000000000..a46ba54ac14 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_signed.C @@ -0,0 +1,45 @@ +// { dg-do compile { target c++11 } } + +#define SA(X) static_assert((X),#X) + +#define SA_TEST_CATEGORY(TRAIT, X, expect) \ + SA(TRAIT(X) == expect); \ + SA(TRAIT(const X) == expect); \ + SA(TRAIT(volatile X) == expect); \ + SA(TRAIT(const volatile X) == expect) + +SA_TEST_CATEGORY(__is_signed, void, false); + +SA_TEST_CATEGORY(__is_signed, bool, bool(-1) < bool(0)); +SA_TEST_CATEGORY(__is_signed, char, char(-1) < char(0)); +SA_TEST_CATEGORY(__is_signed, signed char, true); +SA_TEST_CATEGORY(__is_signed, unsigned char, false); +SA_TEST_CATEGORY(__is_signed, wchar_t, wchar_t(-1) < wchar_t(0)); +SA_TEST_CATEGORY(__is_signed, short, true); +SA_TEST_CATEGORY(__is_signed, unsigned short, false); +SA_TEST_CATEGORY(__is_signed, int, true); +SA_TEST_CATEGORY(__is_signed, unsigned int, false); +SA_TEST_CATEGORY(__is_signed, long, true); +SA_TEST_CATEGORY(__is_signed, unsigned long, false); +SA_TEST_CATEGORY(__is_signed, long long, true); +SA_TEST_CATEGORY(__is_signed, unsigned long long, false); + +SA_TEST_CATEGORY(__is_signed, float, true); +SA_TEST_CATEGORY(__is_signed, double, true); +SA_TEST_CATEGORY(__is_signed, long double, true); + +#ifndef __STRICT_ANSI__ +// GNU Extensions. +#ifdef __SIZEOF_INT128__ +SA_TEST_CATEGORY(__is_signed, __int128, true); +SA_TEST_CATEGORY(__is_signed, unsigned __int128, false); +#endif + +#ifdef _GLIBCXX_USE_FLOAT128 +SA_TEST_CATEGORY(__is_signed, __float128, true); +#endif +#endif + +// Sanity check. +class ClassType { }; +SA_TEST_CATEGORY(__is_signed, ClassType, false); -- 2.43.0