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. 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)); -- 2.41.0.113.g6640c2d06d