We currently ICE upon the following invalid code, because we don't check
that the template parameters in a member class template specialization
are correct.
=== 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 ===
This patch fixes the PR by calling redeclare_class_template.
PR c++/115716
gcc/cp/ChangeLog:
* pt.cc (maybe_process_partial_specialization): Call
redeclare_class_template.
gcc/testsuite/ChangeLog:
* g++.dg/template/spec42.C: New test.
* g++.dg/template/spec43.C: New test.
type, inst);
}
+ /* Make sure that the specialization is valid. */
+ if (!redeclare_class_template (type, current_template_parms,
+ current_template_constraints ()))
+ 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. */
--- /dev/null
+// PR c++/115716
+// { dg-do compile }
+template <typename T> struct x {
+ template <typename U> struct y { // { dg-note "used 1 template parameter" }
+ typedef T result2;
+ };
+};
+
+template<>
+template<typename U, typename>
+struct x<int>::y { // { dg-error "redeclared with 2 template parameters" }
+ typedef double result2;
+};
+
+int main() {
+ x<int>::y<int>::result2 xxx2;
+}
--- /dev/null
+// PR c++/115716
+// { dg-do compile { target c++20 } }
+template <typename T> struct x {
+ template <typename U> struct y { // { dg-note "original" }
+ typedef T result2;
+ };
+};
+
+template<>
+template<typename U>
+requires true
+struct x<int>::y { // { dg-error "different constraints" }
+ typedef double result2;
+};
+
+int main() {
+ x<int>::y<int>::result2 xxx2;
+}