OSDN Git Service

Fix PR c++/43800
authordodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Apr 2010 19:23:45 +0000 (19:23 +0000)
committerdodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Apr 2010 19:23:45 +0000 (19:23 +0000)
gcc/cp/ChangeLog:
PR c++/43800
PR c++/43704
* typeck.c (incompatible_dependent_types_p): If one of the
compared types if not a typedef then honour their main variant
equivalence.

gcc/testsuite/ChangeLog:
PR c++/43800
PR c++/43704
* g++.dg/template/typedef32.C: Adjust.
* g++.dg/template/typedef33.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158571 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/typedef32.C
gcc/testsuite/g++.dg/template/typedef33.C [new file with mode: 0644]

index 8c264f5..83945e2 100644 (file)
@@ -1,3 +1,11 @@
+2010-04-20  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/43800
+       PR c++/43704
+       * typeck.c (incompatible_dependent_types_p): If one of the
+       compared types if not a typedef then honour their main variant
+       equivalence.
+
 2010-04-20  Jakub Jelinek  <jakub@redhat.com>
 
        * cp-tree.h (TYPE_REF_IS_RVALUE): Remove.
index c43cf33..bc699a1 100644 (file)
@@ -1155,6 +1155,7 @@ static bool
 incompatible_dependent_types_p (tree t1, tree t2)
 {
   tree tparms1 = NULL_TREE, tparms2 = NULL_TREE;
+  bool t1_typedef_variant_p, t2_typedef_variant_p;
 
   if (!uses_template_parms (t1) || !uses_template_parms (t2))
     return false;
@@ -1167,10 +1168,22 @@ incompatible_dependent_types_p (tree t1, tree t2)
        return true;
     }
 
+  t1_typedef_variant_p = typedef_variant_p (t1);
+  t2_typedef_variant_p = typedef_variant_p (t2);
+
   /* Either T1 or T2 must be a typedef.  */
-  if (!typedef_variant_p (t1) && !typedef_variant_p (t2))
+  if (!t1_typedef_variant_p && !t2_typedef_variant_p)
     return false;
 
+  if (!t1_typedef_variant_p || !t2_typedef_variant_p)
+    /* Either T1 or T2 is not a typedef so we cannot compare the
+       the template parms of the typedefs of T1 and T2.
+       At this point, if the main variant type of T1 and T2 are equal
+       it means the two types can't be incompatible, from the perspective
+       of this function.  */
+    if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
+      return false;
+
   /* So if we reach this point, it means either T1 or T2 is a typedef variant.
      Let's compare their template parameters.  */
 
index 3f1d530..186c8ae 100644 (file)
@@ -1,3 +1,10 @@
+2010-04-20  Dodji Seketeli  <dodji@redhat.com>
+
+       PR c++/43800
+       PR c++/43704
+       * g++.dg/template/typedef32.C: Adjust.
+       * g++.dg/template/typedef33.C: New test.
+
 2010-04-20  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/43227
index b3c4b90..b32e66c 100644 (file)
@@ -10,12 +10,13 @@ struct if_
 template<class I1>
 struct iterator_restrict_traits
 {
+    struct iterator_category {};
 };
 
 template<class T>
-class matrix
+struct matrix
 {
class ci {};
struct ci {struct ic {};};
  class i {};
 };
 
diff --git a/gcc/testsuite/g++.dg/template/typedef33.C b/gcc/testsuite/g++.dg/template/typedef33.C
new file mode 100644 (file)
index 0000000..1d2117b
--- /dev/null
@@ -0,0 +1,21 @@
+// Origin PR c++/43800
+// { dg-do compile }
+
+template<class T, class U=T>
+struct V
+{
+  typedef T t_type;
+};
+
+template<class T>
+class J
+{
+  typedef typename V<T>::t_type t_type; 
+  const t_type& f(); // #0:
+private:
+  t_type b;
+};
+
+template<class T>
+const typename V<T>::t_type& J<T>::f() {return b;} // #1
+