diff options
author | Douglas Gregor <doug.gregor@gmail.com> | 2007-09-24 12:14:57 +0000 |
---|---|---|
committer | Doug Gregor <dgregor@gcc.gnu.org> | 2007-09-24 12:14:57 +0000 |
commit | 714f2304c65dde0653e36cb94c5cefaea2727d55 (patch) | |
tree | 43fb0347a8b05451a453a47db18a6cc43185d35e /gcc/cp | |
parent | 996caac6daf068f5db3b8455db336c1df62ec4f9 (diff) | |
download | gcc-714f2304c65dde0653e36cb94c5cefaea2727d55.zip gcc-714f2304c65dde0653e36cb94c5cefaea2727d55.tar.gz gcc-714f2304c65dde0653e36cb94c5cefaea2727d55.tar.bz2 |
re PR c++/33112 (ICE : canonical types differ for identical types const _CharT* [14] and const _CharT* [14])
2007-09-24 Douglas Gregor <doug.gregor@gmail.com>
PR c++/33112
PR c++/33185
* tree.c (cplus_array_compare): Compare pointers, not types.
(build_cplus_array_type_1): Store new array type into the hash
table before building the canonical type; build the canonical type
correctly.
(cp_build_qualified_type_real): Put all of the array types with
cv-qualified element types into the C++ array hash table, built as
variants of the unqualified versions.
From-SVN: r128711
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/tree.c | 119 |
2 files changed, 61 insertions, 70 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 79e96c6..ed3c7ff 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2007-09-24 Douglas Gregor <doug.gregor@gmail.com> + + PR c++/33112 + PR c++/33185 + * tree.c (cplus_array_compare): Compare pointers, not types. + (build_cplus_array_type_1): Store new array type into the hash + table before building the canonical type; build the canonical type + correctly. + (cp_build_qualified_type_real): Put all of the array types with + cv-qualified element types into the C++ array hash table, built as + variants of the unqualified versions. + 2007-09-23 Jason Merrill <jason@redhat.com> PR c++/16370 diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 9a1ad13..5f46cbd 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -512,18 +512,12 @@ cplus_array_compare (const void * k1, const void * k2) const_tree const t1 = (const_tree) k1; const cplus_array_info *const t2 = (const cplus_array_info*) k2; - if (!comptypes (TREE_TYPE (t1), t2->type, COMPARE_STRUCTURAL)) - return 0; - - if (!TYPE_DOMAIN (t1)) - return !t2->domain; - - if (!t2->domain) - return 0; - - return comptypes (TYPE_DOMAIN (t1), t2->domain, COMPARE_STRUCTURAL); + return (TREE_TYPE (t1) == t2->type && TYPE_DOMAIN (t1) == t2->domain); } +/* Hash table containing all of the C++ array types, including + dependent array types and array types whose element type is + cv-qualified. */ static GTY ((param_is (union tree_node))) htab_t cplus_array_htab; @@ -542,7 +536,7 @@ build_cplus_array_type_1 (tree elt_type, tree index_type) void **e; cplus_array_info cai; hashval_t hash; - + if (cplus_array_htab == NULL) cplus_array_htab = htab_create_ggc (61, &cplus_array_hash, &cplus_array_compare, NULL); @@ -554,31 +548,31 @@ build_cplus_array_type_1 (tree elt_type, tree index_type) e = htab_find_slot_with_hash (cplus_array_htab, &cai, hash, INSERT); if (*e) - /* We have found the type: we're done. */ + /* We have found the type: we're done. */ return (tree) *e; else { - /* Build a new array type. */ + /* Build a new array type. */ t = make_node (ARRAY_TYPE); TREE_TYPE (t) = elt_type; TYPE_DOMAIN (t) = index_type; - /* Complete building the array type. */ + /* Store it in the hash table. */ + *e = t; + + /* Set the canonical type for this new node. */ if (TYPE_STRUCTURAL_EQUALITY_P (elt_type) || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type))) SET_TYPE_STRUCTURAL_EQUALITY (t); else if (TYPE_CANONICAL (elt_type) != elt_type || (index_type && TYPE_CANONICAL (index_type) != index_type)) - TYPE_CANONICAL (t) - = TYPE_CANONICAL - (build_cplus_array_type_1 (TYPE_CANONICAL (elt_type), - index_type? - TYPE_CANONICAL (index_type) - : index_type)); - - /* Store it in the hash table. */ - *e = t; + TYPE_CANONICAL (t) + = build_cplus_array_type + (TYPE_CANONICAL (elt_type), + index_type? TYPE_CANONICAL (index_type) : index_type); + else + TYPE_CANONICAL (t) = t; } } else @@ -713,59 +707,44 @@ cp_build_qualified_type_real (tree type, if (!t) { - tree domain = TYPE_DOMAIN (type); + tree index_type = TYPE_DOMAIN (type); + void **e; + cplus_array_info cai; + hashval_t hash; + + if (cplus_array_htab == NULL) + cplus_array_htab = htab_create_ggc (61, &cplus_array_hash, + &cplus_array_compare, + NULL); + + hash = (htab_hash_pointer (element_type) + ^ htab_hash_pointer (index_type)); + cai.type = element_type; + cai.domain = index_type; + + e = htab_find_slot_with_hash (cplus_array_htab, &cai, hash, INSERT); + if (*e) + /* We have found the type: we're done. */ + return (tree) *e; - /* Make a new array type, just like the old one, but with the - appropriately qualified element type. */ + /* Build a new array type and add it into the table. */ t = build_variant_type_copy (type); TREE_TYPE (t) = element_type; + *e = t; - /* This is a new type. */ - TYPE_CANONICAL (t) = t; - - if (dependent_type_p (element_type) - || (domain - && value_dependent_expression_p (TYPE_MAX_VALUE (domain)))) - { - /* The new dependent array type we just created might be - equivalent to an existing dependent array type, so we - need to keep track of this new array type with a - lookup into CPLUS_ARRAY_HTAB. Note that we cannot - directly call build_cplus_array_type (that would - recurse) or build_cplus_array_type_1 (that would lose - attributes). */ - void **e; - cplus_array_info cai; - hashval_t hash; - - if (cplus_array_htab == NULL) - cplus_array_htab = htab_create_ggc (61, &cplus_array_hash, - &cplus_array_compare, - NULL); - - hash = (htab_hash_pointer (element_type) - ^ htab_hash_pointer (domain)); - cai.type = element_type; - cai.domain = domain; - - e = htab_find_slot_with_hash (cplus_array_htab, &cai, hash, - INSERT); - if (! *e) - /* Save this new type. */ - *e = t; - } - - if (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (t)) - || (TYPE_DOMAIN (t) - && TYPE_STRUCTURAL_EQUALITY_P (TYPE_DOMAIN (t)))) + /* Set the canonical type for this new node. */ + if (TYPE_STRUCTURAL_EQUALITY_P (element_type) + || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type))) SET_TYPE_STRUCTURAL_EQUALITY (t); + else if (TYPE_CANONICAL (element_type) != element_type + || (index_type + && TYPE_CANONICAL (index_type) != index_type)) + TYPE_CANONICAL (t) + = build_cplus_array_type + (TYPE_CANONICAL (element_type), + index_type? TYPE_CANONICAL (index_type) : index_type); else - TYPE_CANONICAL (t) - = TYPE_CANONICAL - (build_array_type (TYPE_CANONICAL (TREE_TYPE (t)), - TYPE_DOMAIN (t)? - TYPE_CANONICAL (TYPE_DOMAIN(t)) - : TYPE_DOMAIN (t))); + TYPE_CANONICAL (t) = t; } /* Even if we already had this variant, we update |