This is DR 2032 which says that the restrictions regarding template parameter packs and default arguments apply to variable templates as well, but we weren't detecting that.
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? gcc/cp/ChangeLog: DR 2032 PR c++/96218 * pt.c (check_default_tmpl_args): Also consider variable templates. gcc/testsuite/ChangeLog: DR 2032 PR c++/96218 * g++.dg/cpp1y/var-templ67.C: New test. --- gcc/cp/pt.c | 5 +++-- gcc/testsuite/g++.dg/cpp1y/var-templ67.C | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/var-templ67.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4e1c77a6bd7..b74074a092b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5481,14 +5481,15 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary, /* Don't complain about an enclosing partial specialization. */ && parm_level == parms - && TREE_CODE (decl) == TYPE_DECL + && (TREE_CODE (decl) == TYPE_DECL || VAR_P (decl)) && i < ntparms - 1 && template_parameter_pack_p (TREE_VALUE (parm)) /* A fixed parameter pack will be partially instantiated into a fixed length list. */ && !fixed_parameter_pack_p (TREE_VALUE (parm))) { - /* A primary class template can only have one + /* A primary class template, primary variable template + (DR 2032), or alias template can only have one parameter pack, at the end of the template parameter list. */ diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ67.C b/gcc/testsuite/g++.dg/cpp1y/var-templ67.C new file mode 100644 index 00000000000..f36af39bc19 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ67.C @@ -0,0 +1,16 @@ +// DR 2032 - Default template-arguments of variable templates +// PR c++/96218 +// { dg-do compile { target c++14 } } + +// [temp.param]/14: If a template-parameter of a class template, variable +// template, or alias template has a default template-argument, each subsequent +// template-parameter shall either have a default template-argument supplied or +// be a template parameter pack. +template<typename T = int, typename U> +T vt; // { dg-error "no default argument" } + +// [temp.param]/14: If a template-parameter of a primary class template, +// primary variable template, or alias template is a template parameter pack, +// it shall be the last template-parameter. +template<typename... Ts, typename U> // { dg-error "must be at the end" } +int vt2; base-commit: 866c5bfd9c3ebc00913f3a84eb5383b51f2aee16 -- 2.26.2