Here the template arguments for the partial specialization are valid arguments for the template, but not for a partial specialization, because 'd' can never be deduced to anything other than an empty pack.
Tested x86_64-pc-linux-gnu, applying to 8/9/10. gcc/cp/ChangeLog 2020-03-14 Jason Merrill <ja...@redhat.com> PR c++/92068 * pt.c (process_partial_specialization): Error rather than crash on extra pack expansion. --- gcc/cp/pt.c | 9 ++++++++- gcc/testsuite/g++.dg/cpp0x/variadic178.C | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/variadic178.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index bd2f9be82ea..48ac48615a0 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5038,6 +5038,14 @@ process_partial_specialization (tree decl) return decl; } + else if (nargs > DECL_NTPARMS (maintmpl)) + { + error ("too many arguments for partial specialization %qT", type); + inform (DECL_SOURCE_LOCATION (maintmpl), "primary template here"); + /* Avoid crash below. */ + return decl; + } + /* If we aren't in a dependent class, we can actually try deduction. */ else if (tpd.level == 1 /* FIXME we should be able to handle a partial specialization of a @@ -5064,7 +5072,6 @@ process_partial_specialization (tree decl) Also, we verify that pack expansions only occur at the end of the argument list. */ - gcc_assert (nargs == DECL_NTPARMS (maintmpl)); tpd2.parms = 0; for (i = 0; i < nargs; ++i) { diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic178.C b/gcc/testsuite/g++.dg/cpp0x/variadic178.C new file mode 100644 index 00000000000..f0e65958de3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic178.C @@ -0,0 +1,6 @@ +// PR c++/92068 +// { dg-do compile { target c++11 } } + +template <typename, typename> struct a; +template <typename b, typename c, typename... d> +struct a<b, c, d...> { }; // { dg-error "arguments" } base-commit: 53b28abf8e4ba37e47d3bb05476e0a80ae761567 -- 2.18.1