aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/pt.c7
-rw-r--r--gcc/stor-layout.c5
-rw-r--r--gcc/testsuite/ChangeLog2
-rw-r--r--gcc/testsuite/g++.dg/template/array22.C14
-rw-r--r--gcc/tree.c11
7 files changed, 37 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ca2a952..45b83c8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,7 +1,14 @@
+2011-03-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/48029
+ * stor-layout.c (layout_type): Don't set structural equality
+ on arrays of incomplete type.
+ * tree.c (type_hash_eq): Handle comparing them properly.
+
2011-03-10 Jakub Jelinek <jakub@redhat.com>
PR debug/48043
- * config/s390/s390.c (s390_delegitimize_address): Make sure the
+ * config/s390/s390.c (s390_delegitimize_address): Make sure the
result mode matches original rtl mode.
2011-03-10 Nick Clifton <nickc@redhat.com>
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a3a5bf7..a4c394c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2011-03-10 Jason Merrill <jason@redhat.com>
+ PR c++/48029
+ * pt.c (iterative_hash_template_arg): Remove special case for
+ ARRAY_TYPE.
+
PR c++/47198
* parser.c (cp_parser_single_declaration): Just return if
cp_parser_parse_and_diagnose_invalid_type_name complained.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index ac91698..ab2aea3 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1569,13 +1569,6 @@ iterative_hash_template_arg (tree arg, hashval_t val)
val = iterative_hash_object (code, val);
return iterative_hash_template_arg (TREE_OPERAND (arg, 2), val);
- case ARRAY_TYPE:
- /* layout_type sets structural equality for arrays of
- incomplete type, so we can't rely on the canonical type
- for hashing. */
- val = iterative_hash_template_arg (TREE_TYPE (arg), val);
- return iterative_hash_template_arg (TYPE_DOMAIN (arg), val);
-
case LAMBDA_EXPR:
/* A lambda can't appear in a template arg, but don't crash on
erroneous input. */
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 9056d7e..ed36c5b 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -2028,11 +2028,6 @@ layout_type (tree type)
#else
TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT);
#endif
- if (!TYPE_SIZE (element))
- /* We don't know the size of the underlying element type, so
- our alignment calculations will be wrong, forcing us to
- fall back on structural equality. */
- SET_TYPE_STRUCTURAL_EQUALITY (type);
TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
SET_TYPE_MODE (type, BLKmode);
if (TYPE_SIZE (type) != 0
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9739ac8..c3dec73 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,7 @@
2011-03-10 Jason Merrill <jason@redhat.com>
+ * g++.dg/template/array22.C: New.
+
* g++.dg/cpp0x/syntax-err1.C: New.
* g++.dg/parse/error36.C: Adjust expected errors.
* g++.old-deja/g++.pt/ctor2.C: Likewise.
diff --git a/gcc/testsuite/g++.dg/template/array22.C b/gcc/testsuite/g++.dg/template/array22.C
new file mode 100644
index 0000000..e101587
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/array22.C
@@ -0,0 +1,14 @@
+// PR c++/48029
+
+template <class T> struct A { };
+template <class T, class U> struct B
+{
+ struct N { };
+ typedef U u;
+};
+
+typedef B<int, A<int>(*)[2]> btype;
+A<int> v1[2];
+btype v2;
+
+
diff --git a/gcc/tree.c b/gcc/tree.c
index c947072..2e1b9a3 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -5981,12 +5981,19 @@ type_hash_eq (const void *va, const void *vb)
|| TREE_TYPE (a->type) != TREE_TYPE (b->type)
|| !attribute_list_equal (TYPE_ATTRIBUTES (a->type),
TYPE_ATTRIBUTES (b->type))
- || TYPE_ALIGN (a->type) != TYPE_ALIGN (b->type)
- || TYPE_MODE (a->type) != TYPE_MODE (b->type)
|| (TREE_CODE (a->type) != COMPLEX_TYPE
&& TYPE_NAME (a->type) != TYPE_NAME (b->type)))
return 0;
+ /* Be careful about comparing arrays before and after the element type
+ has been completed; don't compare TYPE_ALIGN unless both types are
+ complete. */
+ if (COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (a->type)
+ && COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (b->type)
+ && (TYPE_ALIGN (a->type) != TYPE_ALIGN (b->type)
+ || TYPE_MODE (a->type) != TYPE_MODE (b->type)))
+ return 0;
+
switch (TREE_CODE (a->type))
{
case VOID_TYPE: