This patch implements built-in trait for std::is_arithmetic.
gcc/cp/ChangeLog:
* cp-trait.def: Define __is_arithmetic.
* constraint.cc (diagnose_trait_expr): Handle CPTK_IS_ARITHMETIC.
* semantics.cc (trait_expr_value): Likewise.
(finish_trait_expr): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/ext/has-builtin-1.C: Test existence of __is_arithmetic.
* g++.dg/ext/is_arithmetic.C: New test.
* g++.dg/tm/pr46567.C (__is_arithmetic): Rename to ...
(____is_arithmetic): ... this.
* g++.dg/torture/pr57107.C: Likewise.
libstdc++-v3/ChangeLog:
* include/bits/cpp_type_traits.h (__is_arithmetic): Rename to ...
(____is_arithmetic): ... this.
* include/c_global/cmath: Use ____is_arithmetic instead.
* include/c_std/cmath: Likewise.
* include/tr1/cmath: Likewise.
Signed-off-by: Ken Matsui <kmat...@gcc.gnu.org>
---
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_arithmetic.C | 33 ++++++++++++++
gcc/testsuite/g++.dg/tm/pr46567.C | 6 +--
gcc/testsuite/g++.dg/torture/pr57107.C | 4 +-
libstdc++-v3/include/bits/cpp_type_traits.h | 4 +-
libstdc++-v3/include/c_global/cmath | 48 ++++++++++-----------
libstdc++-v3/include/c_std/cmath | 24 +++++------
libstdc++-v3/include/tr1/cmath | 24 +++++------
11 files changed, 99 insertions(+), 55 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/ext/is_arithmetic.C
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 8cf0f2d0974..bd517d08843 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3754,6 +3754,9 @@ diagnose_trait_expr (tree expr, tree args)
case CPTK_IS_AGGREGATE:
inform (loc, " %qT is not an aggregate", t1);
break;
+ case CPTK_IS_ARITHMETIC:
+ inform (loc, " %qT is not an arithmetic type", t1);
+ break;
case CPTK_IS_TRIVIALLY_COPYABLE:
inform (loc, " %qT is not trivially copyable", t1);
break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index 8b7fece0cc8..a95aeeaf778 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -82,6 +82,7 @@ DEFTRAIT_EXPR (IS_TRIVIALLY_ASSIGNABLE,
"__is_trivially_assignable", 2)
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_ARITHMETIC, "__is_arithmetic", 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 8fb47fd179e..4531f047d73 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12118,6 +12118,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree
type2)
case CPTK_IS_UNION:
return type_code1 == UNION_TYPE;
+ case CPTK_IS_ARITHMETIC:
+ return ARITHMETIC_TYPE_P (type1);
+
case CPTK_IS_ASSIGNABLE:
return is_xible (MODIFY_EXPR, type1, type2);
@@ -12296,6 +12299,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_ENUM:
case CPTK_IS_UNION:
case CPTK_IS_SAME:
+ case CPTK_IS_ARITHMETIC:
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 f343e153e56..3d63b0101d1 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -146,3 +146,6 @@
#if !__has_builtin (__remove_cvref)
# error "__has_builtin (__remove_cvref) failed"
#endif
+#if !__has_builtin (__is_arithmetic)
+# error "__has_builtin (__is_arithmetic) failed"
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/is_arithmetic.C
b/gcc/testsuite/g++.dg/ext/is_arithmetic.C
new file mode 100644
index 00000000000..fd35831f646
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_arithmetic.C
@@ -0,0 +1,33 @@
+// { 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_arithmetic, void, false);
+
+SA_TEST_CATEGORY(__is_arithmetic, char, true);
+SA_TEST_CATEGORY(__is_arithmetic, signed char, true);
+SA_TEST_CATEGORY(__is_arithmetic, unsigned char, true);
+SA_TEST_CATEGORY(__is_arithmetic, wchar_t, true);
+SA_TEST_CATEGORY(__is_arithmetic, short, true);
+SA_TEST_CATEGORY(__is_arithmetic, unsigned short, true);
+SA_TEST_CATEGORY(__is_arithmetic, int, true);
+SA_TEST_CATEGORY(__is_arithmetic, unsigned int, true);
+SA_TEST_CATEGORY(__is_arithmetic, long, true);
+SA_TEST_CATEGORY(__is_arithmetic, unsigned long, true);
+SA_TEST_CATEGORY(__is_arithmetic, long long, true);
+SA_TEST_CATEGORY(__is_arithmetic, unsigned long long, true);
+SA_TEST_CATEGORY(__is_arithmetic, float, true);
+SA_TEST_CATEGORY(__is_arithmetic, double, true);
+SA_TEST_CATEGORY(__is_arithmetic, long double, true);
+
+// Sanity check.
+SA_TEST_CATEGORY(__is_arithmetic, ClassType, false);
diff --git a/gcc/testsuite/g++.dg/tm/pr46567.C
b/gcc/testsuite/g++.dg/tm/pr46567.C
index 6d791484448..b16f7b685e7 100644
--- a/gcc/testsuite/g++.dg/tm/pr46567.C
+++ b/gcc/testsuite/g++.dg/tm/pr46567.C
@@ -217,16 +217,16 @@ namespace std __attribute__ ((__visibility__
("default"))) {
typedef __true_type __type;
};
template<typename _Tp>
- struct __is_arithmetic
+ struct ____is_arithmetic
: public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
{ };
template<typename _Tp>
struct __is_fundamental
- : public __traitor<__is_void<_Tp>, __is_arithmetic<_Tp> >
+ : public __traitor<__is_void<_Tp>, ____is_arithmetic<_Tp> >
{ };
template<typename _Tp>
struct __is_scalar
- : public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
+ : public __traitor<____is_arithmetic<_Tp>, __is_pointer<_Tp> >
{ };
template<typename _Tp>
struct __is_char
diff --git a/gcc/testsuite/g++.dg/torture/pr57107.C
b/gcc/testsuite/g++.dg/torture/pr57107.C
index 4dbd32bd298..4329a6eb4e1 100644
--- a/gcc/testsuite/g++.dg/torture/pr57107.C
+++ b/gcc/testsuite/g++.dg/torture/pr57107.C
@@ -25,9 +25,9 @@ namespace std __attribute__ ((__visibility__ ("default"))) {
enum {
__value = 0 };
};
- template<typename _Tp> struct __is_arithmetic : public
__traitor<__is_integer<_Tp>, __is_floating<_Tp> > {
+ template<typename _Tp> struct ____is_arithmetic : public
__traitor<__is_integer<_Tp>, __is_floating<_Tp> > {
};
- template<typename _Tp> struct __is_scalar : public
__traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> > {
+ template<typename _Tp> struct __is_scalar : public
__traitor<____is_arithmetic<_Tp>, __is_pointer<_Tp> > {
};
}
namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) {
diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h
b/libstdc++-v3/include/bits/cpp_type_traits.h
index 4312f32a4e0..95c55433c81 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -381,7 +381,7 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
// An arithmetic type is an integer type or a floating point type
//
template<typename _Tp>
- struct __is_arithmetic
+ struct ____is_arithmetic