aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mmitchel@gcc.gnu.org>1998-10-11 17:38:53 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-10-11 17:38:53 +0000
commit6df47b0613bcbf1fc764e4725f1f2812a04884e4 (patch)
tree5b6459c4e5a4e5e20273edeac8b690ed48db7fb2 /gcc
parent4a7bd8e25b9441695adb7923a93fa42a18881a59 (diff)
downloadgcc-6df47b0613bcbf1fc764e4725f1f2812a04884e4.zip
gcc-6df47b0613bcbf1fc764e4725f1f2812a04884e4.tar.gz
gcc-6df47b0613bcbf1fc764e4725f1f2812a04884e4.tar.bz2
cp-tree.h (specializations_of_same_template_p): Declare.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/pt.c30
-rw-r--r--gcc/cp/search.c6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memclass17.C22
4 files changed, 53 insertions, 6 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1584557..e09fca8 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 478c0b9..6a6aac6 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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;
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index be6cffc..5905674 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -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
index 0000000..96024e2
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memclass17.C
@@ -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());
+}