aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorDouglas Gregor <doug.gregor@gmail.com>2007-11-06 14:39:41 +0000
committerDoug Gregor <dgregor@gcc.gnu.org>2007-11-06 14:39:41 +0000
commit9ae165a0722366ba1ee877d1099d147a506d0135 (patch)
tree24adf8f3c491cb12e5443e2f7b4ae5687c9ed263 /gcc/c-common.c
parent1ad8aeeb962a281f654be3bc0a7a2dd4015d317b (diff)
downloadgcc-9ae165a0722366ba1ee877d1099d147a506d0135.zip
gcc-9ae165a0722366ba1ee877d1099d147a506d0135.tar.gz
gcc-9ae165a0722366ba1ee877d1099d147a506d0135.tar.bz2
re PR c++/33977 (internal compiler error: canonical types differ for identical types const char [5] and const sal_Char [5])
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++/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-06 Douglas Gregor <doug.gregor@gmail.com> PR c++/33977 PR c++/33886 * g++.dg/other/canon-array.C: New. From-SVN: r129929
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c77
1 files changed, 13 insertions, 64 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index bdb8d80..763745a 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -3086,70 +3086,6 @@ static void def_builtin_1 (enum built_in_function fncode,
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. */
@@ -7044,6 +6980,19 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
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