+2006-10-26 Paolo Bonzini <bonzini@gnu.org>
+
+ PR c/29092
+
+ * c-typeck.c (digest_init): Always allow initializing vectors
+ that have static storage duration with compound literals.
+ * tree.c (build_type_attribute_qual_variant): New, based on
+ build_type_attribute_variant.
+ (build_type_attribute_variant): Rewrite using the former.
+ (make_vector_type): Use build_type_attribute_qual_variant to build
+ type variants. Use type_hash_canon on the others.
+
2006-10-19 Eric Botcazou <ebotcazou@adacore.com>
* fold-const.c (add_double): Rename to add_double_with_sign.
conversion. */
inside_init = convert (type, inside_init);
- if (require_constant && !flag_isoc99
+ if (require_constant
+ && (code == VECTOR_TYPE || !flag_isoc99)
&& TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
{
/* As an extension, allow initializing objects with static storage
duration with compound literals (which are then treated just as
- the brace enclosed list they contain). */
+ the brace enclosed list they contain). Also allow this for
+ vectors, as we can only assign them with compound literals. */
tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
inside_init = DECL_INITIAL (decl);
}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -std=gnu89" } */
+
+/* Ensure that we don't need a typedef to initialize a vector type. */
+#define vector __attribute__ ((vector_size (8)))
+vector char x = (vector char) {1,2,3,4,5,6,7,8}; /* { dg-bogus "initializer" } */
+vector char y = (vector short) {1,2,3,4}; /* { dg-error "initializer" } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -std=gnu99" } */
+
+/* Ensure that we don't need a typedef to initialize a vector type. */
+#define vector __attribute__ ((vector_size (8)))
+vector char x = (vector char) {1,2,3,4,5,6,7,8}; /* { dg-bogus "initializer" } */
+vector char y = (vector short) {1,2,3,4}; /* { dg-error "initializer" } */
}
/* Return a type like TTYPE except that its TYPE_ATTRIBUTE
- is ATTRIBUTE.
+ is ATTRIBUTE and its qualifiers are QUALS.
Record such modified types already made so we don't make duplicates. */
-tree
-build_type_attribute_variant (tree ttype, tree attribute)
+static tree
+build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
{
if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute))
{
}
ntype = type_hash_canon (hashcode, ntype);
- ttype = build_qualified_type (ntype, TYPE_QUALS (ttype));
+ ttype = build_qualified_type (ntype, quals);
}
return ttype;
}
+/* Return a type like TTYPE except that its TYPE_ATTRIBUTE
+ is ATTRIBUTE.
+
+ Record such modified types already made so we don't make duplicates. */
+
+tree
+build_type_attribute_variant (tree ttype, tree attribute)
+{
+ return build_type_attribute_qual_variant (ttype, attribute,
+ TYPE_QUALS (ttype));
+}
+
/* Return nonzero if IDENT is a valid name for attribute ATTR,
or zero if not.
static tree
make_vector_type (tree innertype, int nunits, enum machine_mode mode)
{
- tree t = make_node (VECTOR_TYPE);
+ tree t;
+ hashval_t hashcode = 0;
+ /* Build a main variant, based on the main variant of the inner type, then
+ use it to build the variant we return. */
+ if (TYPE_ATTRIBUTES (innertype) || TYPE_QUALS (innertype))
+ return build_type_attribute_qual_variant (
+ make_vector_type (TYPE_MAIN_VARIANT (innertype), nunits, mode),
+ TYPE_ATTRIBUTES (innertype),
+ TYPE_QUALS (innertype));
+
+ t = make_node (VECTOR_TYPE);
TREE_TYPE (t) = TYPE_MAIN_VARIANT (innertype);
TYPE_VECTOR_SUBPARTS (t) = nunits;
TYPE_MODE (t) = mode;
TYPE_UID (rt) = TYPE_UID (t);
}
- /* Build our main variant, based on the main variant of the inner type. */
- if (TYPE_MAIN_VARIANT (innertype) != innertype)
- {
- tree innertype_main_variant = TYPE_MAIN_VARIANT (innertype);
- unsigned int hash = TYPE_HASH (innertype_main_variant);
- TYPE_MAIN_VARIANT (t)
- = type_hash_canon (hash, make_vector_type (innertype_main_variant,
- nunits, mode));
- }
-
- return t;
+ hashcode = iterative_hash_host_wide_int (VECTOR_TYPE, hashcode);
+ hashcode = iterative_hash_host_wide_int (mode, hashcode);
+ hashcode = iterative_hash_object (TYPE_HASH (innertype), hashcode);
+ return type_hash_canon (hashcode, t);
}
static tree