We currently ICE upon the following invalid code, because we don't check the number of template parameters in member class template specializations. This patch fixes the PR by adding such a check.
=== cut here === template <typename T> struct x { template <typename U> struct y { typedef T result2; }; }; template<> template<typename U, typename> struct x<int>::y { typedef double result2; }; int main() { x<int>::y<int>::result2 xxx2; } === cut here === Successfully tested on x86_64-pc-linux-gnu. PR c++/115716 gcc/cp/ChangeLog: * pt.cc (maybe_process_partial_specialization): Check number of template parameters in specialization. gcc/testsuite/ChangeLog: * g++.dg/template/spec42.C: New test. --- gcc/cp/pt.cc | 14 ++++++++++++++ gcc/testsuite/g++.dg/template/spec42.C | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 gcc/testsuite/g++.dg/template/spec42.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index bc3ad5edcc5..db8c2a3b4de 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -1173,6 +1173,20 @@ maybe_process_partial_specialization (tree type) type, inst); } + /* Check that the number of template parameters matches the template + being specialized. */ + gcc_assert (current_template_parms); + if (TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS + (CLASSTYPE_TI_ARGS (type))) + != TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS + (current_template_parms))) + { + error ("wrong number of template parameters for %qT", type); + inform (DECL_SOURCE_LOCATION (tmpl), "from definition of %q#D", + tmpl); + return error_mark_node; + } + /* Mark TYPE as a specialization. And as a result, we only have one level of template argument for the innermost class template. */ diff --git a/gcc/testsuite/g++.dg/template/spec42.C b/gcc/testsuite/g++.dg/template/spec42.C new file mode 100644 index 00000000000..e00a48d12a9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/spec42.C @@ -0,0 +1,17 @@ +// PR c++/115716 +// { dg-do compile } +template <typename T> struct x { + template <typename U> struct y { // { dg-note "from definition" } + typedef T result2; + }; +}; + +template<> +template<typename U, typename> +struct x<int>::y { // { dg-error "wrong number" } + typedef double result2; +}; + +int main() { + x<int>::y<int>::result2 xxx2; +} -- 2.44.0