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

Jason Merrill jason@redhat.com
Thu Jun 10 20:16:13 GMT 2021


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



More information about the Gcc-patches mailing list