diff options
author | Simon Martin <simon@nasilyan.com> | 2024-08-25 21:59:31 +0200 |
---|---|---|
committer | Simon Martin <simon@nasilyan.com> | 2024-08-26 18:18:31 +0200 |
commit | 26ee954476bef7328d2cf45928c3c9b84df77178 (patch) | |
tree | 4ad4c054e606f303fbd782598ecc9735a6a2819e /gcc | |
parent | cc372be5d0a8a1665bc5f716458f326b5afad43f (diff) | |
download | gcc-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.cc | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/spec42.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/spec43.C | 18 |
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; +} |