c++: matching deduced template template parameters [PR67829]
authorPatrick Palka <ppalka@redhat.com>
Thu, 10 Jun 2021 22:31:21 +0000 (18:31 -0400)
committerPatrick Palka <ppalka@redhat.com>
Thu, 10 Jun 2021 22:31:21 +0000 (18:31 -0400)
During deduction, when the template of the argument for a bound ttp
is a template template parameter, we need to consider the
TEMPLATE_TEMPLATE_PARAMETER for matching rather than the TEMPLATE_DECL
thereof, because the canonical form of a template template parameter as
a template argument is the former tree, not the latter.

PR c++/67829

gcc/cp/ChangeLog:

* pt.c (unify) <case BOUND_TEMPLATE_TEMPLATE_PARM>: When
the TEMPLATE_DECL of a BOUND_TEMPLATE_TEMPLATE_PARM argument is
a template template parameter, adjust to the
TEMPLATE_TEMPLATE_PARAMETER before falling through.

gcc/testsuite/ChangeLog:

* g++.dg/template/ttp34.C: New test.
* g++.dg/template/ttp34a.C: New test.
* g++.dg/template/ttp34b.C: New test.

gcc/cp/pt.c
gcc/testsuite/g++.dg/template/ttp34.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/ttp34a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/ttp34b.C [new file with mode: 0644]

index b0155a9..d87382d 100644 (file)
@@ -23555,6 +23555,10 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
            return 1;
 
          arg = TYPE_TI_TEMPLATE (arg);
+         if (DECL_TEMPLATE_TEMPLATE_PARM_P (arg))
+           /* If the template is a template template parameter, use the
+              TEMPLATE_TEMPLATE_PARM for matching.  */
+           arg = TREE_TYPE (arg);
 
          /* Fall through to deduce template name.  */
        }
diff --git a/gcc/testsuite/g++.dg/template/ttp34.C b/gcc/testsuite/g++.dg/template/ttp34.C
new file mode 100644 (file)
index 0000000..6709406
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/67829
+
+template<class> class Purr;
+
+template<template<class> class, class, class>
+class Meow;
+
+template<template<class> class P>
+class Meow<P, P<int>, int> { }; // 1
+
+template<template<class> class P, class T>
+class Meow<P, P<int>, T>; // 2
+
+Meow<Purr, Purr<int>, int> kitty;
diff --git a/gcc/testsuite/g++.dg/template/ttp34a.C b/gcc/testsuite/g++.dg/template/ttp34a.C
new file mode 100644 (file)
index 0000000..e3303dc
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/67829
+
+template<class> class Purr;
+
+template<template<class> class, class>
+class Meow;
+
+template<template<class> class P>
+class Meow<P, P<int> > { }; // 1
+
+template<template<class> class P, class T>
+class Meow<P, P<T> >; // 2
+
+Meow<Purr, Purr<int> > kitty;
diff --git a/gcc/testsuite/g++.dg/template/ttp34b.C b/gcc/testsuite/g++.dg/template/ttp34b.C
new file mode 100644 (file)
index 0000000..ed3b3e8
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/67829
+
+template<class> class Purr;
+
+template<class, template<class> class>
+class Meow;
+
+template<template<class> class P>
+class Meow<P<int>, P> { }; // 1
+
+template<template<class> class P, class T>
+class Meow<P<T>, P>; // 2
+
+Meow<Purr<int>, Purr> kitty;