This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PR54442 build_qualified_type produces a non-canonical type
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Cc: jason at redhat dot com
- Date: Mon, 9 Jun 2014 16:18:09 +0200 (CEST)
- Subject: PR54442 build_qualified_type produces a non-canonical type
- Authentication-results: sourceware.org; auth=none
Hello,
in this PR, we end up with 3 types A, B and C such that
TYPE_CANONICAL(A)=B and TYPE_CANONICAL(B)=C. I don't think that is
supposed to happen. Here, build_qualified_type fills in TYPE_CANONICAL(A)
by calling build_qualified_type (so get_qualified_type), which afaics
isn't guaranteed to return a canonical type.
I doubt the patch can be wrong, but it may be that this is a situation
that is not supposed to happen and should be fixed elsewhere?
Bootstrap+testsuite on x86_64-linux-gnu.
2014-06-09 Marc Glisse <marc.glisse@inria.fr>
PR c++/54442
gcc/
* tree.c (build_qualified_type): Use a canonical type for
TYPE_CANONICAL.
gcc/testsuite/
* g++.dg/pr54442.C: New file.
--
Marc Glisse
Index: gcc/testsuite/g++.dg/pr54442.C
===================================================================
--- gcc/testsuite/g++.dg/pr54442.C (revision 0)
+++ gcc/testsuite/g++.dg/pr54442.C (working copy)
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+struct S
+{
+ void s (int) const throw ();
+ void s (int) throw ();
+};
+
+typedef int index_t;
+
+void (S::*f) (index_t) = &S::s;
+void (S::*g) (index_t) const = &S::s;
Index: gcc/tree.c
===================================================================
--- gcc/tree.c (revision 211374)
+++ gcc/tree.c (working copy)
@@ -6319,22 +6319,25 @@ build_qualified_type (tree type, int typ
TYPE_ALIGN (t) = TYPE_ALIGN (atomic_type);
}
}
if (TYPE_STRUCTURAL_EQUALITY_P (type))
/* Propagate structural equality. */
SET_TYPE_STRUCTURAL_EQUALITY (t);
else if (TYPE_CANONICAL (type) != type)
/* Build the underlying canonical type, since it is different
from TYPE. */
- TYPE_CANONICAL (t) = build_qualified_type (TYPE_CANONICAL (type),
- type_quals);
+ {
+ tree c = build_qualified_type (TYPE_CANONICAL (type),
+ type_quals);
+ TYPE_CANONICAL (t) = TYPE_CANONICAL (c);
+ }
else
/* T is its own canonical type. */
TYPE_CANONICAL (t) = t;
}
return t;
}
/* Create a variant of type T with alignment ALIGN. */