aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-02-16 01:05:09 -0500
committerJason Merrill <jason@gcc.gnu.org>2010-02-16 01:05:09 -0500
commit38e40fcd450c508dbacdd2ddcd40ed1e500c4713 (patch)
tree40fe916d8d35dae1dbd625b7ed0a84e18d0c48da
parentd96f5ff5b4afaafb6acdfd4eb407f1d99561dc25 (diff)
downloadgcc-38e40fcd450c508dbacdd2ddcd40ed1e500c4713.zip
gcc-38e40fcd450c508dbacdd2ddcd40ed1e500c4713.tar.gz
gcc-38e40fcd450c508dbacdd2ddcd40ed1e500c4713.tar.bz2
re PR c++/43036 (c++ compilation hang)
PR c++/43036 * tree.c (build_cplus_array_type): Set TYPE_MAIN_VARIANT to strip cv-quals from element here. (cp_build_qualified_type_real): Not here. Preserve typedef name. From-SVN: r156792
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/tree.c84
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/other/array6.C11
4 files changed, 56 insertions, 51 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0b96f4c..8b9bc62 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2010-02-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/43036
+ * tree.c (build_cplus_array_type): Set TYPE_MAIN_VARIANT to strip
+ cv-quals from element here.
+ (cp_build_qualified_type_real): Not here. Preserve typedef name.
+
2010-02-14 Jason Merrill <jason@redhat.com>
PR c++/41997
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d2ab4f0..31b54f6 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -41,7 +41,6 @@ along with GCC; see the file COPYING3. If not see
static tree bot_manip (tree *, int *, void *);
static tree bot_replace (tree *, int *, void *);
-static tree build_cplus_array_type_1 (tree, tree);
static int list_hash_eq (const void *, const void *);
static hashval_t list_hash_pieces (tree, tree, tree);
static hashval_t list_hash (const void *);
@@ -601,14 +600,14 @@ cplus_array_compare (const void * k1, const void * k2)
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. */
+/* Hash table containing dependent array types, which are unsuitable for
+ the language-independent type hash table. */
static GTY ((param_is (union tree_node))) htab_t cplus_array_htab;
+/* Like build_array_type, but handle special C++ semantics. */
-static tree
-build_cplus_array_type_1 (tree elt_type, tree index_type)
+tree
+build_cplus_array_type (tree elt_type, tree index_type)
{
tree t;
@@ -665,6 +664,20 @@ build_cplus_array_type_1 (tree elt_type, tree index_type)
else
t = build_array_type (elt_type, index_type);
+ /* We want TYPE_MAIN_VARIANT of an array to strip cv-quals from the
+ element type as well, so fix it up if needed. */
+ if (elt_type != TYPE_MAIN_VARIANT (elt_type))
+ {
+ tree m = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type),
+ index_type);
+ if (TYPE_MAIN_VARIANT (t) != m)
+ {
+ TYPE_MAIN_VARIANT (t) = m;
+ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
+ TYPE_NEXT_VARIANT (m) = t;
+ }
+ }
+
/* Push these needs up so that initialization takes place
more easily. */
TYPE_NEEDS_CONSTRUCTING (t)
@@ -674,23 +687,6 @@ build_cplus_array_type_1 (tree elt_type, tree index_type)
return t;
}
-tree
-build_cplus_array_type (tree elt_type, tree index_type)
-{
- tree t;
- int type_quals = cp_type_quals (elt_type);
-
- if (type_quals != TYPE_UNQUALIFIED)
- elt_type = cp_build_qualified_type (elt_type, TYPE_UNQUALIFIED);
-
- t = build_cplus_array_type_1 (elt_type, index_type);
-
- if (type_quals != TYPE_UNQUALIFIED)
- t = cp_build_qualified_type (t, type_quals);
-
- return t;
-}
-
/* Return an ARRAY_TYPE with element type ELT and length N. */
tree
@@ -811,41 +807,27 @@ cp_build_qualified_type_real (tree type,
if (element_type == error_mark_node)
return error_mark_node;
- /* See if we already have an identically qualified type. */
+ /* See if we already have an identically qualified type. Tests
+ should be equivalent to those in check_qualified_type. */
for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
if (cp_type_quals (t) == type_quals
&& TYPE_NAME (t) == TYPE_NAME (type)
- && TYPE_CONTEXT (t) == TYPE_CONTEXT (type))
+ && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
+ && attribute_list_equal (TYPE_ATTRIBUTES (t),
+ TYPE_ATTRIBUTES (type)))
break;
if (!t)
- {
- t = build_cplus_array_type_1 (element_type, TYPE_DOMAIN (type));
+ {
+ t = build_cplus_array_type (element_type, TYPE_DOMAIN (type));
- if (TYPE_MAIN_VARIANT (t) != TYPE_MAIN_VARIANT (type))
- {
- /* Set the main variant of the newly-created ARRAY_TYPE
- (with cv-qualified element type) to the main variant of
- the unqualified ARRAY_TYPE we started with. */
- tree last_variant = t;
- tree m = TYPE_MAIN_VARIANT (type);
-
- /* Find the last variant on the new ARRAY_TYPEs list of
- variants, setting the main variant of each of the other
- types to the main variant of our unqualified
- ARRAY_TYPE. */
- while (TYPE_NEXT_VARIANT (last_variant))
- {
- TYPE_MAIN_VARIANT (last_variant) = m;
- last_variant = TYPE_NEXT_VARIANT (last_variant);
- }
-
- /* Splice in the newly-created variants. */
- TYPE_NEXT_VARIANT (last_variant) = TYPE_NEXT_VARIANT (m);
- TYPE_NEXT_VARIANT (m) = t;
- TYPE_MAIN_VARIANT (last_variant) = m;
- }
- }
+ /* Keep the typedef name. */
+ if (TYPE_NAME (t) != TYPE_NAME (type))
+ {
+ t = build_variant_type_copy (t);
+ TYPE_NAME (t) = TYPE_NAME (type);
+ }
+ }
/* Even if we already had this variant, we update
TYPE_NEEDS_CONSTRUCTING and TYPE_HAS_NONTRIVIAL_DESTRUCTOR in case
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7b74365..f361202 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-02-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/43036
+ * g++.dg/other/array6.C: New.
+
2010-02-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* g++.dg/cpp0x/initlist-opt.C: Bind pic locally.
diff --git a/gcc/testsuite/g++.dg/other/array6.C b/gcc/testsuite/g++.dg/other/array6.C
new file mode 100644
index 0000000..cd02401
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/array6.C
@@ -0,0 +1,11 @@
+// PR c++/43036
+
+typedef char T6[2][8];
+const T6* p1;
+typedef char T[8];
+typedef T T2[2];
+typedef T T3[2];
+typedef char T5[2][8];
+const T2* p2;
+const T5* p3;
+const T3* p4;