@@ -3723,6 +3723,9 @@ diagnose_trait_expr (tree expr, tree args)
case CPTK_IS_BASE_OF:
inform (loc, " %qT is not a base of %qT", t1, t2);
break;
+ case CPTK_IS_BOUNDED_ARRAY:
+ inform (loc, " %qT is not a bounded array", t1);
+ break;
case CPTK_IS_CLASS:
inform (loc, " %qT is not a class", t1);
break;
@@ -62,6 +62,7 @@ DEFTRAIT_EXPR (IS_AGGREGATE, "__is_aggregate", 1)
DEFTRAIT_EXPR (IS_ARRAY, "__is_array", 1)
DEFTRAIT_EXPR (IS_ASSIGNABLE, "__is_assignable", 2)
DEFTRAIT_EXPR (IS_BASE_OF, "__is_base_of", 2)
+DEFTRAIT_EXPR (IS_BOUNDED_ARRAY, "__is_bounded_array", 1)
DEFTRAIT_EXPR (IS_CLASS, "__is_class", 1)
DEFTRAIT_EXPR (IS_CONST, "__is_const", 1)
DEFTRAIT_EXPR (IS_CONSTRUCTIBLE, "__is_constructible", -1)
@@ -42,6 +42,7 @@ struct cp_trait {
"__is_array", CPTK_IS_ARRAY, 1, false
"__is_assignable", CPTK_IS_ASSIGNABLE, 2, false
"__is_base_of", CPTK_IS_BASE_OF, 2, false
+"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, 1, false
"__is_class", CPTK_IS_CLASS, 1, false
"__is_const", CPTK_IS_CONST, 1, false
"__is_constructible", CPTK_IS_CONSTRUCTIBLE, -1, false
@@ -80,7 +80,7 @@ cp_trait_lookup::hash (const char *str, size_t len)
116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
116, 116, 116, 116, 116, 20, 116, 45, 5, 20,
50, 0, 30, 5, 116, 0, 116, 116, 5, 10,
- 30, 0, 5, 116, 10, 30, 5, 0, 5, 116,
+ 30, 0, 5, 116, 10, 30, 5, 0, 25, 116,
116, 5, 116, 116, 116, 116, 116, 116, 116, 116,
116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
116, 116, 116, 116, 116, 116, 116, 116, 116, 116,
@@ -116,7 +116,7 @@ cp_trait_lookup::find (const char *str, size_t len)
{
enum
{
- TOTAL_KEYWORDS = 49,
+ TOTAL_KEYWORDS = 50,
MIN_WORD_LENGTH = 7,
MAX_WORD_LENGTH = 37,
MIN_HASH_VALUE = 7,
@@ -125,54 +125,56 @@ cp_trait_lookup::find (const char *str, size_t len)
static const struct cp_trait wordlist[] =
{
-#line 77 "../../gcc/cp/cp-trait.gperf"
+#line 78 "../../gcc/cp/cp-trait.gperf"
{"__bases", CPTK_BASES, 1, true},
-#line 50 "../../gcc/cp/cp-trait.gperf"
+#line 51 "../../gcc/cp/cp-trait.gperf"
{"__is_enum", CPTK_IS_ENUM, 1, false},
-#line 67 "../../gcc/cp/cp-trait.gperf"
+#line 68 "../../gcc/cp/cp-trait.gperf"
{"__is_union", CPTK_IS_UNION, 1, false},
-#line 71 "../../gcc/cp/cp-trait.gperf"
- {"__remove_cv", CPTK_REMOVE_CV, 1, true},
#line 72 "../../gcc/cp/cp-trait.gperf"
+ {"__remove_cv", CPTK_REMOVE_CV, 1, true},
+#line 73 "../../gcc/cp/cp-trait.gperf"
{"__remove_cvref", CPTK_REMOVE_CVREF, 1, true},
-#line 49 "../../gcc/cp/cp-trait.gperf"
+#line 50 "../../gcc/cp/cp-trait.gperf"
{"__is_empty", CPTK_IS_EMPTY, 1, false},
-#line 62 "../../gcc/cp/cp-trait.gperf"
+#line 63 "../../gcc/cp/cp-trait.gperf"
{"__is_trivial", CPTK_IS_TRIVIAL, 1, false},
-#line 73 "../../gcc/cp/cp-trait.gperf"
+#line 74 "../../gcc/cp/cp-trait.gperf"
{"__remove_reference", CPTK_REMOVE_REFERENCE, 1, true},
-#line 78 "../../gcc/cp/cp-trait.gperf"
+#line 79 "../../gcc/cp/cp-trait.gperf"
{"__direct_bases", CPTK_DIRECT_BASES, 1, true},
-#line 75 "../../gcc/cp/cp-trait.gperf"
+#line 76 "../../gcc/cp/cp-trait.gperf"
{"__underlying_type", CPTK_UNDERLYING_TYPE, 1, true},
-#line 68 "../../gcc/cp/cp-trait.gperf"
- {"__is_volatile", CPTK_IS_VOLATILE, 1, false},
-#line 74 "../../gcc/cp/cp-trait.gperf"
+#line 45 "../../gcc/cp/cp-trait.gperf"
+ {"__is_bounded_array", CPTK_IS_BOUNDED_ARRAY, 1, false},
+#line 75 "../../gcc/cp/cp-trait.gperf"
{"__type_pack_element", CPTK_TYPE_PACK_ELEMENT, -1, true},
-#line 66 "../../gcc/cp/cp-trait.gperf"
+#line 67 "../../gcc/cp/cp-trait.gperf"
{"__is_unbounded_array", CPTK_IS_UNBOUNDED_ARRAY, 1, false},
-#line 59 "../../gcc/cp/cp-trait.gperf"
+#line 60 "../../gcc/cp/cp-trait.gperf"
{"__is_polymorphic", CPTK_IS_POLYMORPHIC, 1, false},
-#line 53 "../../gcc/cp/cp-trait.gperf"
+#line 54 "../../gcc/cp/cp-trait.gperf"
{"__is_literal_type", CPTK_IS_LITERAL_TYPE, 1, false},
-#line 65 "../../gcc/cp/cp-trait.gperf"
+#line 66 "../../gcc/cp/cp-trait.gperf"
{"__is_trivially_copyable", CPTK_IS_TRIVIALLY_COPYABLE, 1, false},
-#line 63 "../../gcc/cp/cp-trait.gperf"
+#line 64 "../../gcc/cp/cp-trait.gperf"
{"__is_trivially_assignable", CPTK_IS_TRIVIALLY_ASSIGNABLE, 2, false},
-#line 52 "../../gcc/cp/cp-trait.gperf"
+#line 53 "../../gcc/cp/cp-trait.gperf"
{"__is_layout_compatible", CPTK_IS_LAYOUT_COMPATIBLE, 2, false},
-#line 64 "../../gcc/cp/cp-trait.gperf"
+#line 65 "../../gcc/cp/cp-trait.gperf"
{"__is_trivially_constructible", CPTK_IS_TRIVIALLY_CONSTRUCTIBLE, -1, false},
-#line 70 "../../gcc/cp/cp-trait.gperf"
+#line 71 "../../gcc/cp/cp-trait.gperf"
{"__reference_converts_from_temporary", CPTK_REF_CONVERTS_FROM_TEMPORARY, 2, false},
-#line 69 "../../gcc/cp/cp-trait.gperf"
+#line 70 "../../gcc/cp/cp-trait.gperf"
{"__reference_constructs_from_temporary", CPTK_REF_CONSTRUCTS_FROM_TEMPORARY, 2, false},
#line 33 "../../gcc/cp/cp-trait.gperf"
{"__has_nothrow_copy", CPTK_HAS_NOTHROW_COPY, 1, false},
#line 31 "../../gcc/cp/cp-trait.gperf"
{"__has_nothrow_assign", CPTK_HAS_NOTHROW_ASSIGN, 1, false},
-#line 57 "../../gcc/cp/cp-trait.gperf"
+#line 58 "../../gcc/cp/cp-trait.gperf"
{"__is_pointer_interconvertible_base_of", CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF, 2, false},
+#line 69 "../../gcc/cp/cp-trait.gperf"
+ {"__is_volatile", CPTK_IS_VOLATILE, 1, false},
#line 39 "../../gcc/cp/cp-trait.gperf"
{"__has_virtual_destructor", CPTK_HAS_VIRTUAL_DESTRUCTOR, 1, false},
#line 32 "../../gcc/cp/cp-trait.gperf"
@@ -181,7 +183,7 @@ cp_trait_lookup::find (const char *str, size_t len)
{"__is_base_of", CPTK_IS_BASE_OF, 2, false},
#line 36 "../../gcc/cp/cp-trait.gperf"
{"__has_trivial_copy", CPTK_HAS_TRIVIAL_COPY, 1, false},
-#line 60 "../../gcc/cp/cp-trait.gperf"
+#line 61 "../../gcc/cp/cp-trait.gperf"
{"__is_same", CPTK_IS_SAME, 2, false},
#line 34 "../../gcc/cp/cp-trait.gperf"
{"__has_trivial_assign", CPTK_HAS_TRIVIAL_ASSIGN, 1, false},
@@ -191,27 +193,27 @@ cp_trait_lookup::find (const char *str, size_t len)
{"__has_trivial_destructor", CPTK_HAS_TRIVIAL_DESTRUCTOR, 1, false},
#line 35 "../../gcc/cp/cp-trait.gperf"
{"__has_trivial_constructor", CPTK_HAS_TRIVIAL_CONSTRUCTOR, 1, false},
-#line 54 "../../gcc/cp/cp-trait.gperf"
+#line 55 "../../gcc/cp/cp-trait.gperf"
{"__is_nothrow_assignable", CPTK_IS_NOTHROW_ASSIGNABLE, 2, false},
-#line 56 "../../gcc/cp/cp-trait.gperf"
+#line 57 "../../gcc/cp/cp-trait.gperf"
{"__is_nothrow_convertible", CPTK_IS_NOTHROW_CONVERTIBLE, 2, false},
-#line 46 "../../gcc/cp/cp-trait.gperf"
+#line 47 "../../gcc/cp/cp-trait.gperf"
{"__is_const", CPTK_IS_CONST, 1, false},
-#line 55 "../../gcc/cp/cp-trait.gperf"
+#line 56 "../../gcc/cp/cp-trait.gperf"
{"__is_nothrow_constructible", CPTK_IS_NOTHROW_CONSTRUCTIBLE, -1, false},
-#line 58 "../../gcc/cp/cp-trait.gperf"
+#line 59 "../../gcc/cp/cp-trait.gperf"
{"__is_pod", CPTK_IS_POD, 1, false},
#line 41 "../../gcc/cp/cp-trait.gperf"
{"__is_aggregate", CPTK_IS_AGGREGATE, 1, false},
#line 42 "../../gcc/cp/cp-trait.gperf"
{"__is_array", CPTK_IS_ARRAY, 1, false},
-#line 48 "../../gcc/cp/cp-trait.gperf"
+#line 49 "../../gcc/cp/cp-trait.gperf"
{"__is_convertible", CPTK_IS_CONVERTIBLE, 2, false},
-#line 47 "../../gcc/cp/cp-trait.gperf"
+#line 48 "../../gcc/cp/cp-trait.gperf"
{"__is_constructible", CPTK_IS_CONSTRUCTIBLE, -1, false},
-#line 51 "../../gcc/cp/cp-trait.gperf"
+#line 52 "../../gcc/cp/cp-trait.gperf"
{"__is_final", CPTK_IS_FINAL, 1, false},
-#line 45 "../../gcc/cp/cp-trait.gperf"
+#line 46 "../../gcc/cp/cp-trait.gperf"
{"__is_class", CPTK_IS_CLASS, 1, false},
#line 38 "../../gcc/cp/cp-trait.gperf"
{"__has_unique_object_representations", CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS, 1, false},
@@ -219,9 +221,9 @@ cp_trait_lookup::find (const char *str, size_t len)
{"__is_abstract", CPTK_IS_ABSTRACT, 1, false},
#line 43 "../../gcc/cp/cp-trait.gperf"
{"__is_assignable", CPTK_IS_ASSIGNABLE, 2, false},
-#line 61 "../../gcc/cp/cp-trait.gperf"
+#line 62 "../../gcc/cp/cp-trait.gperf"
{"__is_standard_layout", CPTK_IS_STD_LAYOUT, 1, false},
-#line 76 "../../gcc/cp/cp-trait.gperf"
+#line 77 "../../gcc/cp/cp-trait.gperf"
{"__is_deducible ", CPTK_IS_DEDUCIBLE, 2, false}
};
@@ -230,12 +232,12 @@ cp_trait_lookup::find (const char *str, size_t len)
-1, -1, -1, -1, -1, -1, -1, 0, -1, 1, 2, 3, -1, -1,
4, 5, -1, 6, 7, 8, -1, -1, 9, 10, 11, 12, 13, 14,
15, -1, 16, -1, 17, 18, -1, 19, -1, 20, 21, -1, 22, -1,
- 23, -1, 24, 25, -1, 26, 27, 28, 29, -1, 30, -1, 31, 32,
- -1, -1, 33, 34, 35, 36, -1, 37, 38, 39, 40, -1, 41, -1,
- 42, -1, -1, -1, -1, 43, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 44, -1, -1, 45, -1, 46, -1, -1, -1, -1, 47, -1, -1,
+ 23, 24, 25, 26, -1, 27, 28, 29, 30, -1, 31, -1, 32, 33,
+ -1, -1, 34, 35, 36, 37, -1, 38, 39, 40, 41, -1, 42, -1,
+ 43, -1, -1, -1, -1, 44, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 45, -1, -1, 46, -1, 47, -1, -1, -1, -1, 48, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 48
+ -1, -1, -1, 49
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
@@ -12154,6 +12154,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
&& (same_type_ignoring_top_level_qualifiers_p (type1, type2)
|| DERIVED_FROM_P (type1, type2)));
+ case CPTK_IS_BOUNDED_ARRAY:
+ return type_code1 == ARRAY_TYPE && TYPE_DOMAIN (type1);
+
case CPTK_IS_CLASS:
return NON_UNION_CLASS_TYPE_P (type1);
@@ -12383,6 +12386,7 @@ finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
break;
case CPTK_IS_ARRAY:
+ case CPTK_IS_BOUNDED_ARRAY:
case CPTK_IS_CLASS:
case CPTK_IS_CONST:
case CPTK_IS_ENUM:
@@ -65,6 +65,9 @@
#if !__has_builtin (__is_base_of)
# error "__has_builtin (__is_base_of) failed"
#endif
+#if !__has_builtin (__is_bounded_array)
+# error "__has_builtin (__is_bounded_array) failed"
+#endif
#if !__has_builtin (__is_class)
# error "__has_builtin (__is_class) failed"
#endif
new file mode 100644
@@ -0,0 +1,38 @@
+// { dg-do compile { target c++11 } }
+
+#include <testsuite_tr1.h>
+
+using namespace __gnu_test;
+
+#define SA(X) static_assert((X),#X)
+
+#define SA_TEST_CONST(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)
+
+SA_TEST_CATEGORY(__is_bounded_array, int[2], true);
+SA_TEST_CATEGORY(__is_bounded_array, int[], false);
+SA_TEST_CATEGORY(__is_bounded_array, int[2][3], true);
+SA_TEST_CATEGORY(__is_bounded_array, int[][3], false);
+SA_TEST_CATEGORY(__is_bounded_array, float*[2], true);
+SA_TEST_CATEGORY(__is_bounded_array, float*[], false);
+SA_TEST_CATEGORY(__is_bounded_array, float*[2][3], true);
+SA_TEST_CATEGORY(__is_bounded_array, float*[][3], false);
+SA_TEST_CATEGORY(__is_bounded_array, ClassType[2], true);
+SA_TEST_CATEGORY(__is_bounded_array, ClassType[], false);
+SA_TEST_CATEGORY(__is_bounded_array, ClassType[2][3], true);
+SA_TEST_CATEGORY(__is_bounded_array, ClassType[][3], false);
+SA_TEST_CATEGORY(__is_bounded_array, int(*)[2], false);
+SA_TEST_CATEGORY(__is_bounded_array, int(*)[], false);
+SA_TEST_CATEGORY(__is_bounded_array, int(&)[2], false);
+SA_TEST_CONST(__is_bounded_array, int(&)[], false);
+
+// Sanity check.
+SA_TEST_CATEGORY(__is_bounded_array, ClassType, false);
+SA_TEST_CONST(__is_bounded_array, void(), false);