aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSimon Martin <simon@nasilyan.com>2024-08-25 21:59:31 +0200
committerSimon Martin <simon@nasilyan.com>2024-08-26 18:18:31 +0200
commit26ee954476bef7328d2cf45928c3c9b84df77178 (patch)
tree4ad4c054e606f303fbd782598ecc9735a6a2819e /gcc
parentcc372be5d0a8a1665bc5f716458f326b5afad43f (diff)
downloadgcc-26ee954476bef7328d2cf45928c3c9b84df77178.zip
gcc-26ee954476bef7328d2cf45928c3c9b84df77178.tar.gz
gcc-26ee954476bef7328d2cf45928c3c9b84df77178.tar.bz2
c++: Check template parameters in member class template specialization [PR115716]
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/pt.cc5
-rw-r--r--gcc/testsuite/g++.dg/template/spec42.C17
-rw-r--r--gcc/testsuite/g++.dg/template/spec43.C18
3 files changed, 40 insertions, 0 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index bc3ad5e..24a6241d 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -1173,6 +1173,11 @@ maybe_process_partial_specialization (tree type)
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. */
diff --git a/gcc/testsuite/g++.dg/template/spec42.C b/gcc/testsuite/g++.dg/template/spec42.C
new file mode 100644
index 0000000..cac1264
--- /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 "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;
+}
diff --git a/gcc/testsuite/g++.dg/template/spec43.C b/gcc/testsuite/g++.dg/template/spec43.C
new file mode 100644
index 0000000..d33659d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/spec43.C
@@ -0,0 +1,18 @@
+// 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;
+}