On 4/11/19 11:20 AM, Paolo Carlini wrote:
Hi,
over the last few days I spent some time on this regression, which at
first seemed just a minor error-recovery issue, but then I noticed that
very slightly tweeking the original testcase uncovered a pretty serious
ICE on valid:
template<typename SX, typename ...XE> void
fk (XE..., int/*SW*/);
void
w9 (void)
{
fk<int> (0);
}
The regression has to do with the changes committed by Jason for
c++/86932, in particular with the condition in coerce_template_parms:
if (template_parameter_pack_p (TREE_VALUE (parm))
&& (arg || !(complain & tf_partial))
&& !(arg && ARGUMENT_PACK_P (arg)))
which has the additional (arg || !complain & tf_partial)) false for the
present testcase, thus the null arg is not changed into an empty pack,
thus later instantiate_template calls check_instantiated_args which
finds it still null and crashes. Now, likely some additional analysis is
in order, but for sure there is an important difference between the
testcase which came with c++/86932 and the above: non-type vs type
template parameter pack. It seems to me that the kind of problem fixed
in c++/86932 cannot occur with type packs, because it boils down to a
reference to a previous parm (full disclosure: the comments and logic in
fixed_parameter_pack_p helped me a lot here). Thus I had the idea of
simply restricting the scope of the new condition above by adding an ||
TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL, which definitely leads to a
clean testsuite and a proper behavior on the new testcases, AFAICS. I'm
attaching what I tested on x86_64-linux.
I think the important property here is that it's non-terminal, not that
it's a type pack. We can't deduce anything for a non-terminal pack, so
we should go ahead and make an empty pack.
Jason