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.
Thanks, Paolo.
//////////////////////
Index: cp/pt.c
===================================================================
--- cp/pt.c (revision 270279)
+++ cp/pt.c (working copy)
@@ -8475,7 +8475,8 @@ coerce_template_parms (tree parms,
arg = NULL_TREE;
if (template_parameter_pack_p (TREE_VALUE (parm))
- && (arg || !(complain & tf_partial))
+ && (arg || !(complain & tf_partial)
+ || TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL)
&& !(arg && ARGUMENT_PACK_P (arg)))
{
/* Some arguments will be placed in the
Index: testsuite/g++.dg/cpp0x/pr89900-1.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr89900-1.C (nonexistent)
+++ testsuite/g++.dg/cpp0x/pr89900-1.C (working copy)
@@ -0,0 +1,10 @@
+// { dg-do compile { target c++11 } }
+
+template<typename SX, typename ...XE> void
+fk (XE..., SW); // { dg-error "12:.SW. has not been declared" }
+
+void
+w9 (void)
+{
+ fk<int> (0);
+}
Index: testsuite/g++.dg/cpp0x/pr89900-2.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr89900-2.C (nonexistent)
+++ testsuite/g++.dg/cpp0x/pr89900-2.C (working copy)
@@ -0,0 +1,10 @@
+// { dg-do compile { target c++11 } }
+
+template<typename SX, typename ...XE> void
+fk (XE..., int);
+
+void
+w9 (void)
+{
+ fk<int> (0);
+}