diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index b161c9b2c9e..78f100d2745 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3802,6 +3802,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_SIGNED:
       inform (loc, "  %qT is not a signed type", t1);
       break;
diff --git a/gcc/cp/cp-trait.def b/gcc/cp/cp-trait.def
index b0faa4c8937..08a2780c929 100644
--- a/gcc/cp/cp-trait.def
+++ b/gcc/cp/cp-trait.def
@@ -86,6 +86,7 @@ DEFTRAIT_EXPR (IS_POINTER, "__is_pointer", 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_SIGNED, "__is_signed", 1)
 DEFTRAIT_EXPR (IS_SCOPED_ENUM, "__is_scoped_enum", 1)
 DEFTRAIT_EXPR (IS_STD_LAYOUT, "__is_standard_layout", 1)
diff --git a/gcc/cp/cp-trait.gperf b/gcc/cp/cp-trait.gperf
index 67a1e37d754..654da0568ec 100644
--- a/gcc/cp/cp-trait.gperf
+++ b/gcc/cp/cp-trait.gperf
@@ -67,6 +67,7 @@ struct cp_trait {
 "__is_polymorphic", CPTK_IS_POLYMORPHIC, false, false, false
 "__is_reference", CPTK_IS_REFERENCE, false, false, false
 "__is_same", CPTK_IS_SAME, true, false, false
+"__is_scalar", CPTK_IS_SCALAR, false, false, false
 "__is_signed", CPTK_IS_SIGNED, false, false, false
 "__is_scoped_enum", CPTK_IS_SCOPED_ENUM, false, false, false
 "__is_standard_layout", CPTK_IS_STD_LAYOUT, false, false, false
diff --git a/gcc/cp/cp-trait.h b/gcc/cp/cp-trait.h
index dd94ac56fec..3c13835a8df 100644
--- a/gcc/cp/cp-trait.h
+++ b/gcc/cp/cp-trait.h
@@ -80,10 +80,10 @@ cp_trait_lookup::hash (const char *str, size_t len)
       126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
       126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
       126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
-      126, 126, 126, 126, 126,  20, 126,  40,  45,  50,
-       55,   0,   5,  15, 126,   0, 126, 126,  35,  10,
-       35,   0,  10, 126,  30,   5,   5,  16,  30, 126,
-      126,  10, 126, 126, 126, 126, 126, 126, 126, 126,
+      126, 126, 126, 126, 126,  40, 126,  25,  21,  50,
+        0,   0,  30,  10, 126,   0, 126, 126,  25,   5,
+       50,   0,  61, 126,  10,  10,   5,   0,  15, 126,
+      126,   5, 126, 126, 126, 126, 126, 126, 126, 126,
       126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
       126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
       126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
@@ -118,7 +118,7 @@ cp_trait_lookup::find (const char *str, size_t len)
 {
   enum
     {
-      TOTAL_KEYWORDS = 61,
+      TOTAL_KEYWORDS = 62,
       MIN_WORD_LENGTH = 7,
       MAX_WORD_LENGTH = 37,
       MIN_HASH_VALUE = 7,
@@ -127,141 +127,143 @@ cp_trait_lookup::find (const char *str, size_t len)
 
   static const struct cp_trait wordlist[] =
     {
-#line 90 "../../gcc/cp/cp-trait.gperf"
+#line 91 "../../gcc/cp/cp-trait.gperf"
       {"__bases", CPTK_BASES, false, false, true},
-#line 83 "../../gcc/cp/cp-trait.gperf"
-      {"__remove_cv", CPTK_REMOVE_CV, false, false, true},
+#line 53 "../../gcc/cp/cp-trait.gperf"
+      {"__is_enum", CPTK_IS_ENUM, false, false, false},
+#line 79 "../../gcc/cp/cp-trait.gperf"
+      {"__is_union", CPTK_IS_UNION, false, false, false},
 #line 84 "../../gcc/cp/cp-trait.gperf"
-      {"__remove_cvref", CPTK_REMOVE_CVREF, false, false, true},
+      {"__remove_cv", CPTK_REMOVE_CV, false, false, true},
 #line 85 "../../gcc/cp/cp-trait.gperf"
+      {"__remove_cvref", CPTK_REMOVE_CVREF, false, false, true},
+#line 90 "../../gcc/cp/cp-trait.gperf"
+      {"__is_deducible ", CPTK_IS_DEDUCIBLE, true, false, false},
+#line 86 "../../gcc/cp/cp-trait.gperf"
       {"__remove_pointer", CPTK_REMOVE_POINTER, false, false, true},
-#line 73 "../../gcc/cp/cp-trait.gperf"
+#line 74 "../../gcc/cp/cp-trait.gperf"
       {"__is_trivial", CPTK_IS_TRIVIAL, false, false, false},
-#line 86 "../../gcc/cp/cp-trait.gperf"
+#line 87 "../../gcc/cp/cp-trait.gperf"
       {"__remove_reference", CPTK_REMOVE_REFERENCE, false, false, true},
-#line 91 "../../gcc/cp/cp-trait.gperf"
+#line 92 "../../gcc/cp/cp-trait.gperf"
       {"__direct_bases", CPTK_DIRECT_BASES, false, false, true},
-#line 52 "../../gcc/cp/cp-trait.gperf"
-      {"__is_empty", CPTK_IS_EMPTY, false, false, false},
-#line 71 "../../gcc/cp/cp-trait.gperf"
-      {"__is_scoped_enum", CPTK_IS_SCOPED_ENUM, false, false, false},
-#line 66 "../../gcc/cp/cp-trait.gperf"
-      {"__is_pointer", CPTK_IS_POINTER, false, false, false},
+#line 80 "../../gcc/cp/cp-trait.gperf"
+      {"__is_unsigned", CPTK_IS_UNSIGNED, false, false, false},
 #line 69 "../../gcc/cp/cp-trait.gperf"
       {"__is_same", CPTK_IS_SAME, true, false, false},
-#line 53 "../../gcc/cp/cp-trait.gperf"
-      {"__is_enum", CPTK_IS_ENUM, false, false, false},
-#line 78 "../../gcc/cp/cp-trait.gperf"
-      {"__is_union", CPTK_IS_UNION, false, false, false},
+#line 72 "../../gcc/cp/cp-trait.gperf"
+      {"__is_scoped_enum", CPTK_IS_SCOPED_ENUM, false, false, false},
 #line 31 "../../gcc/cp/cp-trait.gperf"
       {"__is_same_as", CPTK_IS_SAME, true, false, false},
-#line 76 "../../gcc/cp/cp-trait.gperf"
+#line 77 "../../gcc/cp/cp-trait.gperf"
       {"__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, false, false, false},
-#line 87 "../../gcc/cp/cp-trait.gperf"
-      {"__type_pack_element", CPTK_TYPE_PACK_ELEMENT, false, true, true},
-#line 74 "../../gcc/cp/cp-trait.gperf"
+#line 60 "../../gcc/cp/cp-trait.gperf"
+      {"__is_member_pointer", CPTK_IS_MEMBER_POINTER, false, false, false},
+#line 75 "../../gcc/cp/cp-trait.gperf"
       {"__is_trivially_assignable", CPTK_IS_TRIVIALLY_ASSIGNABLE, true, false, false},
-#line 70 "../../gcc/cp/cp-trait.gperf"
+#line 71 "../../gcc/cp/cp-trait.gperf"
       {"__is_signed", CPTK_IS_SIGNED, false, false, false},
-#line 75 "../../gcc/cp/cp-trait.gperf"
+#line 76 "../../gcc/cp/cp-trait.gperf"
       {"__is_trivially_constructible", CPTK_IS_TRIVIALLY_CONSTRUCTIBLE, false, true, false},
-#line 79 "../../gcc/cp/cp-trait.gperf"
-      {"__is_unsigned", CPTK_IS_UNSIGNED, false, false, false},
-#line 82 "../../gcc/cp/cp-trait.gperf"
+#line 83 "../../gcc/cp/cp-trait.gperf"
       {"__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, true, false, false},
-#line 81 "../../gcc/cp/cp-trait.gperf"
-      {"__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, true, false, false},
-#line 34 "../../gcc/cp/cp-trait.gperf"
-      {"__has_nothrow_copy", CPTK_HAS_NOTHROW_COPY, false, false, false},
-#line 60 "../../gcc/cp/cp-trait.gperf"
-      {"__is_member_pointer", CPTK_IS_MEMBER_POINTER, false, false, false},
-#line 32 "../../gcc/cp/cp-trait.gperf"
-      {"__has_nothrow_assign", CPTK_HAS_NOTHROW_ASSIGN, false, false, false},
-#line 40 "../../gcc/cp/cp-trait.gperf"
-      {"__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, false, false, false},
-#line 33 "../../gcc/cp/cp-trait.gperf"
-      {"__has_nothrow_constructor", CPTK_HAS_NOTHROW_CONSTRUCTOR, false, false, false},
 #line 59 "../../gcc/cp/cp-trait.gperf"
       {"__is_member_object_pointer", CPTK_IS_MEMBER_OBJECT_POINTER, false, false, false},
-#line 64 "../../gcc/cp/cp-trait.gperf"
-      {"__is_pointer_interconvertible_base_of", CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF, true, false, false},
+#line 82 "../../gcc/cp/cp-trait.gperf"
+      {"__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, true, false, false},
 #line 58 "../../gcc/cp/cp-trait.gperf"
       {"__is_member_function_pointer", CPTK_IS_MEMBER_FUNCTION_POINTER, false, false, false},
-#line 68 "../../gcc/cp/cp-trait.gperf"
-      {"__is_reference", CPTK_IS_REFERENCE, false, false, false},
-#line 54 "../../gcc/cp/cp-trait.gperf"
-      {"__is_final", CPTK_IS_FINAL, false, false, false},
-#line 88 "../../gcc/cp/cp-trait.gperf"
-      {"__underlying_type", CPTK_UNDERLYING_TYPE, false, false, true},
-#line 55 "../../gcc/cp/cp-trait.gperf"
-      {"__is_function", CPTK_IS_FUNCTION, false, false, false},
+#line 47 "../../gcc/cp/cp-trait.gperf"
+      {"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, false, false, false},
 #line 43 "../../gcc/cp/cp-trait.gperf"
       {"__is_arithmetic", CPTK_IS_ARITHMETIC, false, false, false},
+#line 78 "../../gcc/cp/cp-trait.gperf"
+      {"__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, false, false, false},
+#line 89 "../../gcc/cp/cp-trait.gperf"
+      {"__underlying_type", CPTK_UNDERLYING_TYPE, false, false, true},
+#line 46 "../../gcc/cp/cp-trait.gperf"
+      {"__is_base_of", CPTK_IS_BASE_OF, true, false, false},
+#line 44 "../../gcc/cp/cp-trait.gperf"
+      {"__is_array", CPTK_IS_ARRAY, false, false, false},
+#line 70 "../../gcc/cp/cp-trait.gperf"
+      {"__is_scalar", CPTK_IS_SCALAR, false, false, false},
 #line 57 "../../gcc/cp/cp-trait.gperf"
       {"__is_literal_type", CPTK_IS_LITERAL_TYPE, false, false, false},
 #line 41 "../../gcc/cp/cp-trait.gperf"
       {"__is_abstract", CPTK_IS_ABSTRACT, false, false, false},
+#line 42 "../../gcc/cp/cp-trait.gperf"
+      {"__is_aggregate", CPTK_IS_AGGREGATE, false, false, false},
 #line 45 "../../gcc/cp/cp-trait.gperf"
       {"__is_assignable", CPTK_IS_ASSIGNABLE, true, false, false},
-#line 67 "../../gcc/cp/cp-trait.gperf"
-      {"__is_polymorphic", CPTK_IS_POLYMORPHIC, false, false, false},
-#line 46 "../../gcc/cp/cp-trait.gperf"
-      {"__is_base_of", CPTK_IS_BASE_OF, true, false, false},
-#line 61 "../../gcc/cp/cp-trait.gperf"
-      {"__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, true, false, false},
-#line 63 "../../gcc/cp/cp-trait.gperf"
-      {"__is_nothrow_convertible", CPTK_IS_NOTHROW_CONVERTIBLE, true, false, false},
-#line 72 "../../gcc/cp/cp-trait.gperf"
-      {"__is_standard_layout", CPTK_IS_STD_LAYOUT, false, false, false},
-#line 62 "../../gcc/cp/cp-trait.gperf"
-      {"__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, false, true, false},
 #line 56 "../../gcc/cp/cp-trait.gperf"
       {"__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, true, false, false},
+#line 81 "../../gcc/cp/cp-trait.gperf"
+      {"__is_volatile", CPTK_IS_VOLATILE, false, false, false},
+#line 68 "../../gcc/cp/cp-trait.gperf"
+      {"__is_reference", CPTK_IS_REFERENCE, false, false, false},
+#line 73 "../../gcc/cp/cp-trait.gperf"
+      {"__is_standard_layout", CPTK_IS_STD_LAYOUT, false, false, false},
+#line 34 "../../gcc/cp/cp-trait.gperf"
+      {"__has_nothrow_copy", CPTK_HAS_NOTHROW_COPY, false, false, false},
+#line 32 "../../gcc/cp/cp-trait.gperf"
+      {"__has_nothrow_assign", CPTK_HAS_NOTHROW_ASSIGN, false, false, false},
+#line 40 "../../gcc/cp/cp-trait.gperf"
+      {"__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, false, false, false},
+#line 33 "../../gcc/cp/cp-trait.gperf"
+      {"__has_nothrow_constructor", CPTK_HAS_NOTHROW_CONSTRUCTOR, false, false, false},
 #line 37 "../../gcc/cp/cp-trait.gperf"
       {"__has_trivial_copy", CPTK_HAS_TRIVIAL_COPY, false, false, false},
-#line 42 "../../gcc/cp/cp-trait.gperf"
-      {"__is_aggregate", CPTK_IS_AGGREGATE, false, false, false},
-#line 35 "../../gcc/cp/cp-trait.gperf"
-      {"__has_trivial_assign", CPTK_HAS_TRIVIAL_ASSIGN, false, false, false},
 #line 65 "../../gcc/cp/cp-trait.gperf"
       {"__is_pod", CPTK_IS_POD, false, false, false},
+#line 35 "../../gcc/cp/cp-trait.gperf"
+      {"__has_trivial_assign", CPTK_HAS_TRIVIAL_ASSIGN, false, false, false},
+#line 52 "../../gcc/cp/cp-trait.gperf"
+      {"__is_empty", CPTK_IS_EMPTY, false, false, false},
+#line 66 "../../gcc/cp/cp-trait.gperf"
+      {"__is_pointer", CPTK_IS_POINTER, false, false, false},
 #line 38 "../../gcc/cp/cp-trait.gperf"
       {"__has_trivial_destructor", CPTK_HAS_TRIVIAL_DESTRUCTOR, false, false, false},
 #line 36 "../../gcc/cp/cp-trait.gperf"
       {"__has_trivial_constructor", CPTK_HAS_TRIVIAL_CONSTRUCTOR, false, false, false},
-#line 80 "../../gcc/cp/cp-trait.gperf"
-      {"__is_volatile", CPTK_IS_VOLATILE, false, false, false},
-#line 47 "../../gcc/cp/cp-trait.gperf"
-      {"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, false, false, false},
-#line 44 "../../gcc/cp/cp-trait.gperf"
-      {"__is_array", CPTK_IS_ARRAY, false, false, false},
-#line 77 "../../gcc/cp/cp-trait.gperf"
-      {"__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, false, false, false},
-#line 39 "../../gcc/cp/cp-trait.gperf"
-      {"__has_unique_object_representations", CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS, false, false, false},
-#line 49 "../../gcc/cp/cp-trait.gperf"
-      {"__is_const", CPTK_IS_CONST, false, false, false},
+#line 61 "../../gcc/cp/cp-trait.gperf"
+      {"__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, true, false, false},
+#line 63 "../../gcc/cp/cp-trait.gperf"
+      {"__is_nothrow_convertible", CPTK_IS_NOTHROW_CONVERTIBLE, true, false, false},
+#line 88 "../../gcc/cp/cp-trait.gperf"
+      {"__type_pack_element", CPTK_TYPE_PACK_ELEMENT, false, true, true},
+#line 62 "../../gcc/cp/cp-trait.gperf"
+      {"__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, false, true, false},
 #line 48 "../../gcc/cp/cp-trait.gperf"
       {"__is_class", CPTK_IS_CLASS, false, false, false},
+#line 54 "../../gcc/cp/cp-trait.gperf"
+      {"__is_final", CPTK_IS_FINAL, false, false, false},
+#line 55 "../../gcc/cp/cp-trait.gperf"
+      {"__is_function", CPTK_IS_FUNCTION, false, false, false},
+#line 64 "../../gcc/cp/cp-trait.gperf"
+      {"__is_pointer_interconvertible_base_of", CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF, true, false, false},
+#line 67 "../../gcc/cp/cp-trait.gperf"
+      {"__is_polymorphic", CPTK_IS_POLYMORPHIC, false, false, false},
+#line 49 "../../gcc/cp/cp-trait.gperf"
+      {"__is_const", CPTK_IS_CONST, false, false, false},
 #line 51 "../../gcc/cp/cp-trait.gperf"
       {"__is_convertible", CPTK_IS_CONVERTIBLE, true, false, false},
 #line 50 "../../gcc/cp/cp-trait.gperf"
       {"__is_constructible", CPTK_IS_CONSTRUCTIBLE, false, true, false},
-#line 89 "../../gcc/cp/cp-trait.gperf"
-      {"__is_deducible ", CPTK_IS_DEDUCIBLE, true, false, false}
+#line 39 "../../gcc/cp/cp-trait.gperf"
+      {"__has_unique_object_representations", CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS, false, false, false}
     };
 
   static const signed char lookup[] =
     {
-      -1, -1, -1, -1, -1, -1, -1,  0, -1, -1, -1,  1, -1, -1,
-       2, -1,  3,  4,  5,  6,  7,  8,  9, -1, 10, 11, 12, 13,
-      14, 15, 16, 17, -1, 18, 19, 20, -1, 21, 22, 23, 24, -1,
-      -1, -1, 25, 26, 27, 28, 29, 30, 31, -1, 32, 33, -1, 34,
-      -1, 35, 36, -1, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
-      47, -1, -1, 48, 49, 50, -1, -1, 51, 52, 53, 54, -1, -1,
-      -1, -1, -1, -1, -1, -1, 55, -1, -1, -1, -1, 56, -1, -1,
-      -1, -1, 57, 58, -1, 59, -1, -1, -1, -1, -1, -1, -1, -1,
-      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 60
+      -1, -1, -1, -1, -1, -1, -1,  0, -1,  1,  2,  3, -1, -1,
+       4,  5,  6,  7,  8,  9, -1, -1, -1, 10, 11, -1, 12, 13,
+      14, 15, 16, 17, -1, 18, -1, 19, 20, 21, 22, 23, 24, 25,
+      26, 27, -1, 28, 29, 30, 31, 32, 33, -1, 34, 35, 36, 37,
+      -1, -1, 38, -1, 39, -1, -1, -1, 40, 41, -1, -1, 42, 43,
+      44, 45, -1, 46, 47, 48, -1, -1, 49, 50, 51, 52, -1, -1,
+      -1, 53, -1, -1, -1, -1, 54, -1, -1, 55, -1, -1, -1, -1,
+      56, -1, -1, -1, 57, -1, -1, -1, -1, -1, -1, -1, 58, -1,
+      -1, -1, -1, -1, 59, -1, 60, -1, -1, -1, -1, -1, -1, 61
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 5e6b2ca37ac..be345f9aa47 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12226,6 +12226,9 @@ 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 SCALAR_TYPE_P (type1);
+
     case CPTK_IS_SIGNED:
       return ARITHMETIC_TYPE_P (type1) && TYPE_SIGN (type1) == SIGNED;
 
@@ -12428,6 +12431,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
     case CPTK_IS_POINTER:
     case CPTK_IS_REFERENCE:
     case CPTK_IS_SAME:
+    case CPTK_IS_SCALAR:
     case CPTK_IS_SIGNED:
     case CPTK_IS_SCOPED_ENUM:
     case CPTK_IS_UNBOUNDED_ARRAY:
diff --git a/gcc/testsuite/g++.dg/ext/has-builtin-1.C b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
index aaf7254df4b..f4f6fed6876 100644
--- a/gcc/testsuite/g++.dg/ext/has-builtin-1.C
+++ b/gcc/testsuite/g++.dg/ext/has-builtin-1.C
@@ -140,6 +140,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_signed)
 # error "__has_builtin (__is_signed) 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..457fddc52fc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_scalar.C
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++11 } }
+
+#include <cstddef>  // std::nullptr_t
+#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)
+
+// volatile return type would cause a warning.
+#define SA_FN_TEST_CATEGORY(TRAIT, TYPE, EXPECT)	\
+  SA(TRAIT(TYPE) == EXPECT);						\
+  SA(TRAIT(const TYPE) == EXPECT)
+
+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_FN_TEST_CATEGORY(__is_scalar, int(*)(int), true);
+SA_TEST_CATEGORY(__is_scalar, int (ClassType::*), true);
+SA_FN_TEST_CATEGORY(__is_scalar, int (ClassType::*) (int), true);
+SA_TEST_CATEGORY(__is_scalar, std::nullptr_t, true);
+
+// Sanity check.
+SA_TEST_CATEGORY(__is_scalar, ClassType, false);
diff --git a/gcc/testsuite/g++.dg/tm/pr46567.C b/gcc/testsuite/g++.dg/tm/pr46567.C
index c891aff20f4..393f936ea72 100644
--- a/gcc/testsuite/g++.dg/tm/pr46567.C
+++ b/gcc/testsuite/g++.dg/tm/pr46567.C
@@ -225,7 +225,7 @@ namespace std __attribute__ ((__visibility__ ("default"))) {
     : public __traitor<__is_void<_Tp>, __is_arith<_Tp> >
     { };
   template<typename _Tp>
-    struct __is_scalar
+    struct __is_scalar_type
     : public __traitor<__is_arith<_Tp>, __is_ptr<_Tp> >
     { };
   template<typename _Tp>
@@ -1325,7 +1325,7 @@ namespace std __attribute__ ((__visibility__ ("default"))) {
     }
   template<typename _ForwardIterator, typename _Tp>
     inline typename
-    __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, void>::__type
+    __gnu_cxx::__enable_if<!__is_scalar_type<_Tp>::__value, void>::__type
     __fill_a(_ForwardIterator __first, _ForwardIterator __last,
        const _Tp& __value)
     {
@@ -1334,7 +1334,7 @@ namespace std __attribute__ ((__visibility__ ("default"))) {
     }
   template<typename _ForwardIterator, typename _Tp>
     inline typename
-    __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, void>::__type
+    __gnu_cxx::__enable_if<__is_scalar_type<_Tp>::__value, void>::__type
     __fill_a(_ForwardIterator __first, _ForwardIterator __last,
       const _Tp& __value)
     {
@@ -1362,7 +1362,7 @@ namespace std __attribute__ ((__visibility__ ("default"))) {
     }
   template<typename _OutputIterator, typename _Size, typename _Tp>
     inline typename
-    __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, _OutputIterator>::__type
+    __gnu_cxx::__enable_if<!__is_scalar_type<_Tp>::__value, _OutputIterator>::__type
     __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value)
     {
       for (; __n > 0; --__n, ++__first)
@@ -1371,7 +1371,7 @@ namespace std __attribute__ ((__visibility__ ("default"))) {
     }
   template<typename _OutputIterator, typename _Size, typename _Tp>
     inline typename
-    __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, _OutputIterator>::__type
+    __gnu_cxx::__enable_if<__is_scalar_type<_Tp>::__value, _OutputIterator>::__type
     __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value)
     {
       const _Tp __tmp = __value;
diff --git a/gcc/testsuite/g++.dg/torture/pr57107.C b/gcc/testsuite/g++.dg/torture/pr57107.C
index da592b9fd23..4d2ef002e08 100644
--- a/gcc/testsuite/g++.dg/torture/pr57107.C
+++ b/gcc/testsuite/g++.dg/torture/pr57107.C
@@ -27,7 +27,7 @@ namespace std __attribute__ ((__visibility__ ("default"))) {
     };
     template<typename _Tp>     struct __is_arith     : public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >     {
     };
-    template<typename _Tp>     struct __is_scalar     : public __traitor<__is_arith<_Tp>, __is_ptr<_Tp> >     {
+    template<typename _Tp>     struct __is_scalar_type     : public __traitor<__is_arith<_Tp>, __is_ptr<_Tp> >     {
     };
 }
 namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) {
@@ -54,7 +54,7 @@ namespace std __attribute__ ((__visibility__ ("default"))) {
     };
     template<typename _Iterator>     inline typename _Niter_base<_Iterator>::iterator_type     __niter_base(_Iterator __it)     {
     }
-    template<typename _OutputIterator, typename _Size, typename _Tp>     inline typename     __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, _OutputIterator>::__type     __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value)     {
+    template<typename _OutputIterator, typename _Size, typename _Tp>     inline typename     __gnu_cxx::__enable_if<!__is_scalar_type<_Tp>::__value, _OutputIterator>::__type     __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value)     {
 	for (__decltype(__n + 0) __niter = __n;
 	     __niter > 0;
 	     --__niter, ++__first)  *__first = __value;
diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h b/libstdc++-v3/include/bits/cpp_type_traits.h
index 51ed5b07716..16980f5b356 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -397,7 +397,7 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
   // A scalar type is an arithmetic type or a pointer type
   // 
   template<typename _Tp>
-    struct __is_scalar
+    struct __is_scalar_type
     : public __traitor<__is_arith<_Tp>, __is_ptr<_Tp> >
     { };
 
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index d1438429487..4e334da0832 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -914,7 +914,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
   template<typename _ForwardIterator, typename _Tp>
     _GLIBCXX20_CONSTEXPR
     inline typename
-    __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, void>::__type
+    __gnu_cxx::__enable_if<!__is_scalar_type<_Tp>::__value, void>::__type
     __fill_a1(_ForwardIterator __first, _ForwardIterator __last,
 	      const _Tp& __value)
     {
@@ -925,7 +925,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
   template<typename _ForwardIterator, typename _Tp>
     _GLIBCXX20_CONSTEXPR
     inline typename
-    __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, void>::__type
+    __gnu_cxx::__enable_if<__is_scalar_type<_Tp>::__value, void>::__type
     __fill_a1(_ForwardIterator __first, _ForwardIterator __last,
 	      const _Tp& __value)
     {
@@ -1063,7 +1063,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
   template<typename _OutputIterator, typename _Size, typename _Tp>
     _GLIBCXX20_CONSTEXPR
     inline typename
-    __gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, _OutputIterator>::__type
+    __gnu_cxx::__enable_if<!__is_scalar_type<_Tp>::__value, _OutputIterator>::__type
     __fill_n_a1(_OutputIterator __first, _Size __n, const _Tp& __value)
     {
       for (; __n > 0; --__n, (void) ++__first)
@@ -1074,7 +1074,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
   template<typename _OutputIterator, typename _Size, typename _Tp>
     _GLIBCXX20_CONSTEXPR
     inline typename
-    __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, _OutputIterator>::__type
+    __gnu_cxx::__enable_if<__is_scalar_type<_Tp>::__value, _OutputIterator>::__type
     __fill_n_a1(_OutputIterator __first, _Size __n, const _Tp& __value)
     {
       const _Tp __tmp = __value;
diff --git a/libstdc++-v3/include/bits/valarray_array.h b/libstdc++-v3/include/bits/valarray_array.h
index 222fd5fd900..558817329ce 100644
--- a/libstdc++-v3/include/bits/valarray_array.h
+++ b/libstdc++-v3/include/bits/valarray_array.h
@@ -90,7 +90,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     inline void
     __valarray_default_construct(_Tp* __b, _Tp* __e)
     {
-      _Array_default_ctor<_Tp, __is_scalar<_Tp>::__value>::_S_do_it(__b, __e);
+      _Array_default_ctor<_Tp, __is_scalar_type<_Tp>::__value>::_S_do_it(__b, __e);
     }
 
   // Turn a raw-memory into an array of _Tp filled with __t
