[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