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