This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] PR c++/42225


Hello,

As we now compare the template parameters of member typedefs decls, I think
strip_typedefs should not strip dependent typedefs anymore.

The example of the patch below is another test case reduced from
the initial big test case attached to this PR.

When we compare the two S0<TTI> (the one from S and the one from foo), we
end up comparing the two typename T::TI - as the TTI typedef is stripped -
and at some point we compare the two T. In one case, T is a typedef,
and in the other case, it's a template parameter. The two Ts are considered
equal, and I think that's correct.

Not stripping the TTI typedef gives us a chance to actually compare the
template parameters of the typedef decl contexts.

Another easy route would be to handle TYPENAME_TYPE in strip_typedefs, but
that would be doing more work than necessary, I think.

The reason why I didn't notice this in the first place is I forgot to test
the previous patch against the _initial_ huge test case that the bug reporter
filed.  I did test it against the reduced test case only. But it appeared we hit
another crash once the first one is fixed by the previous patch.
Sorry about that.

Tested against trunk and the initial test case in bugzilla on
x86_64-unknown-linux

        Dodji

commit 4e8c63a7899cda0445bc0ce2895d2c9cbfdbd45f
Author: Dodji Seketeli <dodji@redhat.com>
Date:   Fri Dec 11 23:03:26 2009 +0100

    Fix PR c++/42225, take 2
    
    gcc/cp/ChangeLog:
    	* tree.c (strip_typedefs): Don't strip dependent typedefs.
    
    gcc/testsuite/ChangeLog:
    	* g++.dg/template/typedef26.C: New test.

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 7097f8c..861f805 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -975,14 +975,18 @@ cv_unqualified (tree type)
     * If T is a type that needs structural equality
       its TYPE_CANONICAL (T) will be NULL.
     * TYPE_CANONICAL (T) desn't carry type attributes
-      and looses template parameter names.   */
+      and looses template parameter names.
+
+   Note that this function does not strip typedefs that are
+   type dependent.  */
 
 tree
 strip_typedefs (tree t)
 {
   tree result = NULL, type = NULL, t0 = NULL;
 
-  if (!t || t == error_mark_node || t == TYPE_CANONICAL (t))
+  if (!t || t == error_mark_node || t == TYPE_CANONICAL (t)
+      || (typedef_variant_p (t) && dependent_type_p (t)))
     return t;
 
   gcc_assert (TYPE_P (t));
diff --git a/gcc/testsuite/g++.dg/template/typedef26.C b/gcc/testsuite/g++.dg/template/typedef26.C
new file mode 100644
index 0000000..d2a6331
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/typedef26.C
@@ -0,0 +1,38 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin: PR c++/42225
+// { dg-do compile }
+
+struct A
+{
+    typedef int TI;
+};
+
+template<class T0>
+struct S0
+{
+    int i;
+};
+
+template<class _T, int>
+struct S1
+{
+    typedef _T T;
+    typedef typename T::TI TTI;
+    typedef S0<TTI> TT0;
+};
+
+template<class T>
+void
+foo(const T&)
+{
+    typedef typename T::TI TTI;
+    typedef S0<TTI> TT1;
+}
+
+int
+main()
+{
+    A a;
+    foo (a);
+}
+


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]