cp-tree.h (specializations_of_same_template_p): Declare.
authorMark Mitchell <mmitchel@gcc.gnu.org>
Sun, 11 Oct 1998 17:38:53 +0000 (17:38 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sun, 11 Oct 1998 17:38:53 +0000 (17:38 +0000)
* cp-tree.h (specializations_of_same_template_p): Declare.
* pt.c (specializations_of_same_template_p): New function.
(unify): Use it.
* search.c (get_template_base): Use it.
(get_template_base_recursive): Likewise.

From-SVN: r22987

gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/search.c
gcc/testsuite/g++.old-deja/g++.pt/memclass17.C [new file with mode: 0644]

index 1584557..e09fca8 100644 (file)
@@ -2869,6 +2869,7 @@ extern int is_specialization_of                 PROTO((tree, tree));
 extern int comp_template_args                   PROTO((tree, tree));
 extern void maybe_process_partial_specialization PROTO((tree));
 extern void maybe_check_template_type           PROTO((tree));
+extern int specializations_of_same_template_p   PROTO((tree, tree));
 
 extern int processing_specialization;
 extern int processing_explicit_instantiation;
index 478c0b9..6a6aac6 100644 (file)
@@ -756,6 +756,22 @@ is_specialization_of (decl, tmpl)
   return 0;
 }
 
+/* Returns nonzero if T1 and T2 are instances of the same template.
+   (They may have different template arguments.)  */
+
+int
+specializations_of_same_template_p (t1, t2)
+     tree t1;
+     tree t2;
+{
+  /* For now, we only deal with instances of class templates, since
+     that is the only way in which this function is used.  */
+
+  return (most_general_template (CLASSTYPE_TI_TEMPLATE (t1))
+         == most_general_template (CLASSTYPE_TI_TEMPLATE (t2)));
+}
+
+
 /* Register the specialization SPEC as a specialization of TMPL with
    the indicated ARGS.  Returns SPEC, or an equivalent prior
    declaration, if available.  */
@@ -7340,12 +7356,18 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
               can be a derived class of the deduced A.  Likewise, if
               P is a pointer to a class of the form template-id, A
               can be a pointer to a derived class pointed to by the
-              deduced A.  */
+              deduced A. 
+
+              The call to get_template_base also handles the case
+              where PARM and ARG are the same type, i.e., where no
+              derivation is involved.  */
            t = get_template_base (CLASSTYPE_TI_TEMPLATE (parm), arg);
-         else if
-           (CLASSTYPE_TEMPLATE_INFO (arg)
-            && CLASSTYPE_TI_TEMPLATE (parm) == CLASSTYPE_TI_TEMPLATE (arg))
+         else if (CLASSTYPE_TEMPLATE_INFO (arg) 
+                  && specializations_of_same_template_p (parm, arg))
+           /* Perhaps PARM is something like S<U> and ARG is S<int>.
+              Then, we should unify `int' and `U'.  */
            t = arg;
+
          if (! t || t == error_mark_node)
            return 1;
 
index be6cffc..5905674 100644 (file)
@@ -3317,7 +3317,8 @@ get_template_base_recursive (binfo, rval, template, via_virtual)
   tree type = BINFO_TYPE (binfo);
 
   if (CLASSTYPE_TEMPLATE_INFO (type)
-      && CLASSTYPE_TI_TEMPLATE (type) == template)
+      && specializations_of_same_template_p (TREE_TYPE (template), 
+                                            type))
     {
       if (rval == NULL_TREE || rval == type)
        return type;
@@ -3375,7 +3376,8 @@ get_template_base (template, binfo)
     my_friendly_abort (92);
 
   if (CLASSTYPE_TEMPLATE_INFO (type)
-      && CLASSTYPE_TI_TEMPLATE (type) == template)
+      && specializations_of_same_template_p (TREE_TYPE (template), 
+                                            type))
     return type;
 
   rval = get_template_base_recursive (binfo, NULL_TREE, template, 0);
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memclass17.C b/gcc/testsuite/g++.old-deja/g++.pt/memclass17.C
new file mode 100644 (file)
index 0000000..96024e2
--- /dev/null
@@ -0,0 +1,22 @@
+// Build don't link:
+
+template <class T> struct S 
+{
+  template <class U> struct I 
+  {
+  };
+
+  S();
+  S(S& s);
+  S(I<T>);
+
+  template <class U> operator I<U>();
+};
+
+S<int> f();
+void g(S<int>);
+
+void h()
+{
+  g(f());
+}