aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <doug.gregor@gmail.com>2008-10-14 15:03:51 +0000
committerDoug Gregor <dgregor@gcc.gnu.org>2008-10-14 15:03:51 +0000
commit9c88061824631d4fc318c57b72cfd1913007d50c (patch)
tree4041d69622227f0600a435b713937d1aef6b5444
parent1fea874e7a0868d3d77c06286226c974237c45e9 (diff)
downloadgcc-9c88061824631d4fc318c57b72cfd1913007d50c.zip
gcc-9c88061824631d4fc318c57b72cfd1913007d50c.tar.gz
gcc-9c88061824631d4fc318c57b72cfd1913007d50c.tar.bz2
re PR c++/37553 (ICE in build_c_cast)
2008-10-14 Douglas Gregor <doug.gregor@gmail.com> PR c++/37553 * tree.c (build_type_attribute_qual_variant): Hash on the unqualified type, and don't overwrite an existing (type_hash_eq): Make the TYPE_NAME of the types significant, to allow distinguishing between wchar_t and its underlying type. This also means that we'll retain a little more typedef information. 2008-10-14 Douglas Gregor <doug.gregor@gmail.com> PR c++/37553 * g++.dg/ext/alias-canon2.C: New. From-SVN: r141111
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/ext/alias-canon2.C36
-rw-r--r--gcc/tree.c11
4 files changed, 56 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1fa7640..6bbf5c2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2008-10-14 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/37553
+ * tree.c (build_type_attribute_qual_variant): Hash on the
+ unqualified type, and don't overwrite an existing
+ (type_hash_eq): Make the TYPE_NAME of the types significant, to
+ allow distinguishing between wchar_t and its underlying type. This
+ also means that we'll retain a little more typedef information.
+
2008-10-14 Andrey Belevantsev <abel@ispras.ru>
Dmitry Melnik <dm@ispras.ru>
Dmitry Zhurikhin <zhur@ispras.ru>
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 32773af..e4f3da8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-10-14 Douglas Gregor <doug.gregor@gmail.com>
+
+ PR c++/37553
+ * g++.dg/ext/alias-canon2.C: New.
+
2008-10-13 Jerry DeLisle <jvdelisle@gcc.gnu.org
PR libfortran/37083
diff --git a/gcc/testsuite/g++.dg/ext/alias-canon2.C b/gcc/testsuite/g++.dg/ext/alias-canon2.C
new file mode 100644
index 0000000..4833db8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/alias-canon2.C
@@ -0,0 +1,36 @@
+// { dg-do compile }
+// PR c++/37553
+typedef unsigned int ui32;
+__extension__ typedef unsigned long long int ui64;
+
+typedef ui32 __attribute__ ((__may_alias__)) ui32a;
+typedef ui64 __attribute__ ((__may_alias__)) ui64a;
+
+union u_u32
+{
+ ui32a v;
+} __attribute__ ((__may_alias__));
+
+union u_u64
+{
+ ui64a v;
+ struct
+ {
+ union u_u32 lo32, hi32;
+ } u;
+} __attribute__ ((__may_alias__));
+
+void
+out_long (ui64 longVal)
+{
+ if ((*(union u_u64 *) &longVal).u.lo32.v < 0x10000000ul)
+ {
+ if ((ui32) ((*(union u_u64 *) &longVal).u.lo32.v) < 0x4000u)
+ {
+ /* do something useful */
+ }
+ }
+}
+
+void f(ui32 *) { }
+void f(ui32a *) { }
diff --git a/gcc/tree.c b/gcc/tree.c
index 33ab8b7..b131a20 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -3704,10 +3704,10 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
return build_qualified_type (ttype, quals);
}
+ ttype = build_qualified_type (ttype, TYPE_UNQUALIFIED);
ntype = build_distinct_type_copy (ttype);
TYPE_ATTRIBUTES (ntype) = attribute;
- set_type_quals (ntype, TYPE_UNQUALIFIED);
hashcode = iterative_hash_object (code, hashcode);
if (TREE_TYPE (ntype))
@@ -3746,12 +3746,11 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
/* If the target-dependent attributes make NTYPE different from
its canonical type, we will need to use structural equality
- checks for this qualified type. */
- ttype = build_qualified_type (ttype, TYPE_UNQUALIFIED);
+ checks for this type. */
if (TYPE_STRUCTURAL_EQUALITY_P (ttype)
|| !targetm.comp_type_attributes (ntype, ttype))
SET_TYPE_STRUCTURAL_EQUALITY (ntype);
- else
+ else if (TYPE_CANONICAL (ntype) == ntype)
TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype);
ttype = build_qualified_type (ntype, quals);
@@ -4585,7 +4584,9 @@ type_hash_eq (const void *va, const void *vb)
|| !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))
+ || TYPE_MODE (a->type) != TYPE_MODE (b->type)
+ || (TREE_CODE (a->type) != COMPLEX_TYPE
+ && TYPE_NAME (a->type) != TYPE_NAME (b->type)))
return 0;
switch (TREE_CODE (a->type))