+2007-11-06 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/33977
+ PR c++/33886
+ * c-common.c (c_build_qualified_type): Moved to c-typeck.c.
+ (complete_array_type): Set canonical type appropriately.
+ * c-typeck.c (c_build_qualified_type): Moved from c-common.c. The
+ C and C++ front ends now have different versions of this function,
+ because the C++ version needs to maintain canonical types here.
+
2007-11-04 Razya Ladelsky <razya@il.ibm.com>
* tree-parloops.c (reduction_info): Remove reduction_init field.
bool both_p, bool fallback_p, bool nonansi_p,
tree fnattrs, bool implicit_p);
-/* Make a variant type in the proper way for C/C++, propagating qualifiers
- down to the element type of an array. */
-
-tree
-c_build_qualified_type (tree type, int type_quals)
-{
- if (type == error_mark_node)
- return type;
-
- if (TREE_CODE (type) == ARRAY_TYPE)
- {
- tree t;
- tree element_type = c_build_qualified_type (TREE_TYPE (type),
- type_quals);
-
- /* See if we already have an identically qualified type. */
- for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
- {
- if (TYPE_QUALS (strip_array_types (t)) == type_quals
- && TYPE_NAME (t) == TYPE_NAME (type)
- && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
- && attribute_list_equal (TYPE_ATTRIBUTES (t),
- TYPE_ATTRIBUTES (type)))
- break;
- }
- if (!t)
- {
- tree domain = TYPE_DOMAIN (type);
-
- t = build_variant_type_copy (type);
- TREE_TYPE (t) = element_type;
-
- if (TYPE_STRUCTURAL_EQUALITY_P (element_type)
- || (domain && TYPE_STRUCTURAL_EQUALITY_P (domain)))
- SET_TYPE_STRUCTURAL_EQUALITY (t);
- else if (TYPE_CANONICAL (element_type) != element_type
- || (domain && TYPE_CANONICAL (domain) != domain))
- {
- tree unqualified_canon
- = build_array_type (TYPE_CANONICAL (element_type),
- domain? TYPE_CANONICAL (domain)
- : NULL_TREE);
- TYPE_CANONICAL (t)
- = c_build_qualified_type (unqualified_canon, type_quals);
- }
- else
- TYPE_CANONICAL (t) = t;
- }
- return t;
- }
-
- /* A restrict-qualified pointer type must be a pointer to object or
- incomplete type. Note that the use of POINTER_TYPE_P also allows
- REFERENCE_TYPEs, which is appropriate for C++. */
- if ((type_quals & TYPE_QUAL_RESTRICT)
- && (!POINTER_TYPE_P (type)
- || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
- {
- error ("invalid use of %<restrict%>");
- type_quals &= ~TYPE_QUAL_RESTRICT;
- }
-
- return build_qualified_type (type, type_quals);
-}
/* Apply the TYPE_QUALS to the new DECL. */
hashcode);
main_type = type_hash_canon (hashcode, main_type);
+ /* Fix the canonical type. */
+ if (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (main_type))
+ || TYPE_STRUCTURAL_EQUALITY_P (TYPE_DOMAIN (main_type)))
+ SET_TYPE_STRUCTURAL_EQUALITY (main_type);
+ else if (TYPE_CANONICAL (TREE_TYPE (main_type)) != TREE_TYPE (main_type)
+ || (TYPE_CANONICAL (TYPE_DOMAIN (main_type))
+ != TYPE_DOMAIN (main_type)))
+ TYPE_CANONICAL (main_type)
+ = build_array_type (TYPE_CANONICAL (TREE_TYPE (main_type)),
+ TYPE_CANONICAL (TYPE_DOMAIN (main_type)));
+ else
+ TYPE_CANONICAL (main_type) = main_type;
+
if (quals == 0)
type = main_type;
else
bitmap_obstack_release (NULL);
return clauses;
}
+
+/* Make a variant type in the proper way for C/C++, propagating qualifiers
+ down to the element type of an array. */
+
+tree
+c_build_qualified_type (tree type, int type_quals)
+{
+ if (type == error_mark_node)
+ return type;
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ tree t;
+ tree element_type = c_build_qualified_type (TREE_TYPE (type),
+ type_quals);
+
+ /* See if we already have an identically qualified type. */
+ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ {
+ if (TYPE_QUALS (strip_array_types (t)) == type_quals
+ && TYPE_NAME (t) == TYPE_NAME (type)
+ && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
+ && attribute_list_equal (TYPE_ATTRIBUTES (t),
+ TYPE_ATTRIBUTES (type)))
+ break;
+ }
+ if (!t)
+ {
+ tree domain = TYPE_DOMAIN (type);
+
+ t = build_variant_type_copy (type);
+ TREE_TYPE (t) = element_type;
+
+ if (TYPE_STRUCTURAL_EQUALITY_P (element_type)
+ || (domain && TYPE_STRUCTURAL_EQUALITY_P (domain)))
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ else if (TYPE_CANONICAL (element_type) != element_type
+ || (domain && TYPE_CANONICAL (domain) != domain))
+ {
+ tree unqualified_canon
+ = build_array_type (TYPE_CANONICAL (element_type),
+ domain? TYPE_CANONICAL (domain)
+ : NULL_TREE);
+ TYPE_CANONICAL (t)
+ = c_build_qualified_type (unqualified_canon, type_quals);
+ }
+ else
+ TYPE_CANONICAL (t) = t;
+ }
+ return t;
+ }
+
+ /* A restrict-qualified pointer type must be a pointer to object or
+ incomplete type. Note that the use of POINTER_TYPE_P also allows
+ REFERENCE_TYPEs, which is appropriate for C++. */
+ if ((type_quals & TYPE_QUAL_RESTRICT)
+ && (!POINTER_TYPE_P (type)
+ || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
+ {
+ error ("invalid use of %<restrict%>");
+ type_quals &= ~TYPE_QUAL_RESTRICT;
+ }
+
+ return build_qualified_type (type, type_quals);
+}
2007-11-06 Douglas Gregor <doug.gregor@gmail.com>
+ PR c++/33977
+ PR c++/33886
+ * tree.c (c_build_qualified_type): Define bridge to
+ cp_build_qualified_type.
+
+2007-11-06 Douglas Gregor <doug.gregor@gmail.com>
+
PR c++/31439
PR c++/32114
PR c++/32115
}
+/* Used by the C++ front end to build qualified array types. However,
+ the C version of this function does not properly maintain canonical
+ types (which are not used in C). */
+tree
+c_build_qualified_type (tree type, int type_quals)
+{
+ return cp_build_qualified_type (type, type_quals);
+}
\f
/* Make a variant of TYPE, qualified with the TYPE_QUALS. Handles
2007-11-06 Douglas Gregor <doug.gregor@gmail.com>
+ PR c++/33977
+ PR c++/33886
+ * g++.dg/other/canon-array.C: New.
+
+2007-11-06 Douglas Gregor <doug.gregor@gmail.com>
+
* testsuite/g++.dg/parser/crash36.C: Tweak expected errors.
* testsuite/g++.dg/cpp0x/pr31439.C: New.
* testsuite/g++.dg/cpp0x/pr32114.C: New.