diff options
author | Douglas Gregor <doug.gregor@gmail.com> | 2007-11-06 14:39:41 +0000 |
---|---|---|
committer | Doug Gregor <dgregor@gcc.gnu.org> | 2007-11-06 14:39:41 +0000 |
commit | 9ae165a0722366ba1ee877d1099d147a506d0135 (patch) | |
tree | 24adf8f3c491cb12e5443e2f7b4ae5687c9ed263 /gcc/c-common.c | |
parent | 1ad8aeeb962a281f654be3bc0a7a2dd4015d317b (diff) | |
download | gcc-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.c | 77 |
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 |