On 6/10/21 3:45 PM, Patrick Palka wrote:
On Thu, 10 Jun 2021, Jason Merrill wrote:

On 6/9/21 3:34 PM, Patrick Palka wrote:
During deduction, when the template of a BOUND_TEMPLATE_TEMPLATE_PARM is
a template template parameter, we need to consider the
TEMPLATE_TEMPLATE_PARAMETER rather than the TEMPLATE_DECL thereof,
because the canonical form of a template template parameter in a
template argument list is the TEMPLATE_TEMPLATE_PARAMETER tree.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

        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                            |  4 ++++
   gcc/testsuite/g++.dg/template/ttp34.C  | 14 ++++++++++++++
   gcc/testsuite/g++.dg/template/ttp34a.C | 14 ++++++++++++++
   gcc/testsuite/g++.dg/template/ttp34b.C | 14 ++++++++++++++
   4 files changed, 46 insertions(+)
   create mode 100644 gcc/testsuite/g++.dg/template/ttp34.C
   create mode 100644 gcc/testsuite/g++.dg/template/ttp34a.C
   create mode 100644 gcc/testsuite/g++.dg/template/ttp34b.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 05679b12973..963a182b9e5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -23555,6 +23555,10 @@ unify (tree tparms, tree targs, tree parm, tree
arg, int strict,
            return 1;
          arg = TYPE_TI_TEMPLATE (arg);
+         if (TREE_CODE (TREE_TYPE (arg)) == TEMPLATE_TEMPLATE_PARM)
+           /* If the template is a template template parameter, use the
+              TEMPLATE_TEMPLATE_PARM for matching.  */
+           arg = TREE_TYPE (arg);

Why don't we need the same thing for non-bound ttp unification?

It seems for non-bound ttp unification, if the argument is itself a ttp
then we can rely on it always being represented as the
TEMPLATE_TEMPLATE_PARAMETER tree instead of as the TEMPLATE_DECL thereof,
so this adjustment isn't necessary.

I tested this empirically with the following assert

@@ -23566,6 +23566,9 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
        if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
           || TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM)
         {
+         if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM
+             && TREE_CODE (arg) == TEMPLATE_DECL)
+           gcc_assert (TREE_CODE (TREE_TYPE (arg)) != TEMPLATE_TEMPLATE_PARM);
           /* Deduce template name TT from TT, TT<>, TT<T> and TT<i>.  */

           /* Simple cases: Value already set, does match or doesn't.  */

which survives the testsuite.

Sounds good. Let's use DECL_TEMPLATE_TEMPLATE_PARM_P for the test; OK with that change.


          /* 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
index 00000000000..67094063ba5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp34.C
@@ -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
index 00000000000..e3303dcf212
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp34a.C
@@ -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
index 00000000000..ed3b3e8ab05
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ttp34b.C
@@ -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;





Reply via email to