OSDN Git Service

Fix PR c++/42225
authordodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 11 Dec 2009 14:36:05 +0000 (14:36 +0000)
committerdodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 11 Dec 2009 14:36:05 +0000 (14:36 +0000)
gcc/cp/ChangeLog:
PR c++/42225
* typeck.c (incompatible_dependent_typedefs_p): New function.
(structural_comptypes): Use it.
* cp-tree.h (cp_set_underlying_type): Declare ...
* tree.c (cp_set_underlying_type): ... new function.
* class.c (build_self_reference): Use cp_set_underlying_type
instead of set_underlying_type.
* decl2.c (grokfield): Likewise.
* name-lookup.c (pushdecl_maybe_friend): Likewise.

gcc/testsuite/ChangeLog:
PR c++/42225
* g++.dg/template/typedef24.C: New test.
* g++.dg/template/typedef25.C: New test.

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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/name-lookup.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/typedef24.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/typedef25.C [new file with mode: 0644]

index 19e751d..988f98f 100644 (file)
@@ -1,5 +1,17 @@
 2009-12-11  Dodji Seketeli  <dodji@redhat.com>
 
+       PR c++/42225
+       * typeck.c (incompatible_dependent_typedefs_p): New function.
+       (structural_comptypes): Use it.
+       * cp-tree.h (cp_set_underlying_type): Declare ...
+       * tree.c (cp_set_underlying_type): ... new function.
+       * class.c (build_self_reference): Use cp_set_underlying_type
+       instead of set_underlying_type.
+       * decl2.c (grokfield): Likewise.
+       * name-lookup.c (pushdecl_maybe_friend): Likewise.
+
+2009-12-11  Dodji Seketeli  <dodji@redhat.com>
+
        PR c++/42251
        * pt.c (convert_template_argument): Avoid missing folding of SCOPE_REFs.
 
index ca75bc1..fff4380 100644 (file)
@@ -6514,7 +6514,7 @@ build_self_reference (void)
   DECL_CONTEXT (value) = current_class_type;
   DECL_ARTIFICIAL (value) = 1;
   SET_DECL_SELF_REFERENCE_P (value);
-  set_underlying_type (value);
+  cp_set_underlying_type (value);
 
   if (processing_template_decl)
     value = push_template_decl (value);
index 21a914d..d0a0435 100644 (file)
@@ -5189,6 +5189,7 @@ extern bool class_tmpl_impl_spec_p                (const_tree);
 extern int zero_init_p                         (const_tree);
 extern tree strip_typedefs                     (tree);
 extern bool typedef_variant_p                  (tree);
+extern void cp_set_underlying_type             (tree);
 extern tree copy_binfo                         (tree, tree, tree,
                                                 tree *, int);
 extern int member_p                            (const_tree);
index d4a866a..2b284fb 100644 (file)
@@ -844,7 +844,7 @@ grokfield (const cp_declarator *declarator,
       if (declspecs->specs[(int)ds_typedef]
           && TREE_TYPE (value) != error_mark_node
           && TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (value))) != value)
-       set_underlying_type (value);
+       cp_set_underlying_type (value);
 
       return value;
     }
index 6b8dcc7..1371c8a 100644 (file)
@@ -874,7 +874,7 @@ pushdecl_maybe_friend (tree x, bool is_friend)
                     inlining.  */
                  && (!TYPE_NAME (type)
                      || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x))))
-           set_underlying_type (x);
+           cp_set_underlying_type (x);
 
          if (type != error_mark_node
              && TYPE_NAME (type)
index 17fc495..7097f8c 100644 (file)
@@ -1076,6 +1076,22 @@ typedef_variant_p (tree type)
   return is_typedef_decl (TYPE_NAME (type));
 }
 
+/* Setup a TYPE_DECL node as a typedef representation.
+   See comments of set_underlying_type in c-common.c.  */
+
+void
+cp_set_underlying_type (tree t)
+{
+  set_underlying_type (t);
+  /* If the typedef variant type is dependent, make it require
+     structural equality.
+     This is useful when comparing two dependent typedef variant types,
+     because it forces the comparison of the template parameters of their
+     decls for instance.  */
+  if (dependent_type_p (TREE_TYPE (t)))
+    SET_TYPE_STRUCTURAL_EQUALITY (TREE_TYPE (t));
+}
+
 \f
 /* Makes a copy of BINFO and TYPE, which is to be inherited into a
    graph dominated by T.  If BINFO is NULL, TYPE is a dependent base,
index 36c0b8a..791b506 100644 (file)
@@ -1073,6 +1073,47 @@ comp_array_types (const_tree t1, const_tree t2, bool allow_redeclaration)
   return true;
 }
 
+/* Subroutine of structural_comptypes.
+   Compare the template parameters of the
+   typedef decl of T1 and T2. 
+   Return TRUE if the template parameters of the typedef decls of T1 and T2 are
+   different, FALSE otherwise.  */
+
+static bool
+incompatible_dependent_typedefs_p (tree t1, tree t2)
+{
+  tree decl1, tinfo1,
+       decl2, tinfo2;
+
+  if (!typedef_variant_p (t1)
+      || !typedef_variant_p (t2)
+      || !dependent_type_p (t1)
+      || !dependent_type_p (t2))
+    return false;
+
+  decl1 = TYPE_NAME (t1);
+  decl2 = TYPE_NAME (t2);
+  if (decl1 == decl2)
+    return false ;
+
+  tinfo1 = get_template_info (decl1);
+  if (!tinfo1)
+    tinfo1 = get_template_info (DECL_CONTEXT (decl1));
+
+  tinfo2 = get_template_info (decl2);
+  if (!tinfo2)
+    tinfo2 = get_template_info (DECL_CONTEXT (decl2));
+
+  gcc_assert (tinfo1 != NULL_TREE
+             && tinfo2 != NULL_TREE);
+
+  if (tinfo1 == tinfo2)
+    return false;
+
+  return !comp_template_parms (DECL_TEMPLATE_PARMS (TI_TEMPLATE (tinfo1)),
+                              DECL_TEMPLATE_PARMS (TI_TEMPLATE (tinfo2)));
+}
+
 /* Subroutine in comptypes.  */
 
 static bool
@@ -1120,6 +1161,9 @@ structural_comptypes (tree t1, tree t2, int strict)
       && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     return true;
 
+  if (incompatible_dependent_typedefs_p (t1, t2))
+    return false;
+
   /* Compare the types.  Break out if they could be the same.  */
   switch (TREE_CODE (t1))
     {
index 9874446..18343a2 100644 (file)
@@ -1,5 +1,11 @@
 2009-12-11  Dodji Seketeli  <dodji@redhat.com>
 
+       PR c++/42225
+       * g++.dg/template/typedef24.C: New test.
+       * g++.dg/template/typedef25.C: New test.
+
+2009-12-11  Dodji Seketeli  <dodji@redhat.com>
+
        PR c++/42251
        * g++.dg/template/const3.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/template/typedef24.C b/gcc/testsuite/g++.dg/template/typedef24.C
new file mode 100644 (file)
index 0000000..ddcae1d
--- /dev/null
@@ -0,0 +1,33 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/42225
+// { dg-do compile }
+
+template<class T>
+struct A
+{
+    typedef T I;
+};
+
+template<class T, int>
+struct B
+{
+    typedef T TT;
+    typedef typename TT::I TT_I;
+    typedef A<TT_I> TA;
+};
+
+template<class T>
+void
+foo()
+{
+    typedef T TT;
+    typedef typename TT::I TT_I;
+    typedef A<TT_I> TA;
+}
+
+int
+main()
+{
+    foo<A<int> >();
+}
+
diff --git a/gcc/testsuite/g++.dg/template/typedef25.C b/gcc/testsuite/g++.dg/template/typedef25.C
new file mode 100644 (file)
index 0000000..4f5868f
--- /dev/null
@@ -0,0 +1,43 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/42225
+// { dg-options "-std=c++0x" }
+// { dg-do compile }
+
+template<class T>
+struct A
+{
+    typedef T I;
+    static const char *i;
+};
+
+template<class T, int>
+struct B
+{
+    typedef T TT;
+    typedef decltype(TT::i)  TT_I0;
+    typedef decltype(&TT::i) TT_I1;
+    typedef decltype(*TT::i) TT_I2;
+    typedef A<TT_I0> TA0;
+    typedef A<TT_I1> TA1;
+    typedef A<TT_I2> TA2;
+};
+
+template<class T>
+void
+foo()
+{
+    typedef T TT;
+    typedef decltype(TT::i)  TT_I0;
+    typedef decltype(&TT::i) TT_I1;
+    typedef decltype(*TT::i) TT_I2;
+    typedef A<TT_I0> TA0;
+    typedef A<TT_I1> TA1;
+    typedef A<TT_I2> TA2;
+}
+
+int
+main()
+{
+    foo<A<int> >();
+}
+