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. > > > /* 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; > > > >