[PATCH] c++: matching deduced template template parameters [PR67829]

Patrick Palka ppalka@redhat.com
Thu Jun 10 19:45:16 GMT 2021


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;
> > 
> 
> 



More information about the Gcc-patches mailing list