On Fri, 23 Jun 2023, Jason Merrill wrote:

> On 6/21/23 13:19, Patrick Palka wrote:
> > When stepping through the variable/alias template specialization code
> > paths, I noticed we perform template argument coercion twice: first from
> > instantiate_alias_template / finish_template_variable and again from
> > tsubst_decl (during instantiate_template).  It should suffice to perform
> > coercion once.
> > 
> > To that end patch elides this second coercion from tsubst_decl when
> > possible.  We can't get rid of it completely because we don't always
> > specialize a variable template from finish_template_variable: we could
> > also be doing so directly from instantiate_template during variable
> > template partial specialization selection, in which case the coercion
> > from tsubst_decl would be the first and only coercion.
> 
> Perhaps we should be coercing in lookup_template_variable rather than
> finish_template_variable?

Ah yes, there's a patch for that at
https://gcc.gnu.org/pipermail/gcc-patches/2023-May/617377.html :)

> It looks like we currently get to
> most_specialized_partial_spec with args that haven't yet been coerced to match
> the primary template.

The call to most_specialized_partial_spec from instantiate_template?
I believe the arguments should already have been coerced by the
caller, which is presumably always finish_template_variable.

So in that patch I also made instantiate_template use
build2 (TEMPLATE_ID_EXPR, ...) directly instead of calling
lookup_template_variable, to avoid an unnecessary double coercion.

> 
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > trunk?  This reduces memory usage of range-v3's zip.cpp by ~0.5%.
> > 
> > gcc/cp/ChangeLog:
> > 
> >     * pt.cc (tsubst_decl) <case TYPE_/VAR_DECL>: Call
> >     coercion_template_parms only if DECL_TEMPLATE_SPECIALIZATION
> >     is set.
> > ---
> >   gcc/cp/pt.cc | 15 +++++++++++----
> >   1 file changed, 11 insertions(+), 4 deletions(-)
> > 
> > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> > index be86051abad..dd10409ce18 100644
> > --- a/gcc/cp/pt.cc
> > +++ b/gcc/cp/pt.cc
> > @@ -15232,10 +15232,17 @@ tsubst_decl (tree t, tree args, tsubst_flags_t
> > complain)
> >             argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl);
> >             if (argvec != error_mark_node
> >                 && PRIMARY_TEMPLATE_P (gen_tmpl)
> > -               && TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (argvec))
> > -             /* We're fully specializing a template declaration, so
> > -                we need to coerce the innermost arguments corresponding
> > to
> > -                the template.  */
> > +               && TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (argvec)
> > +               && DECL_TEMPLATE_SPECIALIZATION (t))
> > +             /* We're fully specializing an alias or variable template,
> > so
> > +                coerce the innermost arguments if necessary.  We expect
> > +                instantiate_alias_template and finish_template_variable
> > to
> > +                already have done this relative to the primary template,
> > in
> > +                which case this coercion is unnecessary, but we can also
> > +                get here when substituting a partial variable template
> > +                specialization (directly from instantiate_template), in
> > +                which case DECL_TEMPLATE_SPECIALIZATION is set and
> > coercion
> > +                is necessary.  */
> >               argvec = (coerce_template_parms
> >                         (DECL_TEMPLATE_PARMS (gen_tmpl),
> >                          argvec, tmpl, complain));
> 
> 

Reply via email to