diff options
author | Jason Merrill <jason@redhat.com> | 2014-09-12 10:39:25 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2014-09-12 10:39:25 -0400 |
commit | 4ee28eb7cea6ebf4713ad1f808d7e5e033ff508a (patch) | |
tree | 19910d805d5cb7cfa642612aea21ce5722033b73 /gcc | |
parent | b6f866946b763415799331fe6799c4528357d6d0 (diff) | |
download | gcc-4ee28eb7cea6ebf4713ad1f808d7e5e033ff508a.zip gcc-4ee28eb7cea6ebf4713ad1f808d7e5e033ff508a.tar.gz gcc-4ee28eb7cea6ebf4713ad1f808d7e5e033ff508a.tar.bz2 |
re PR c++/63201 (Full specialization of a member variable template of a class template does not work)
PR c++/63201
* decl.c (start_decl): Handle specialization of member variable
template.
* pt.c (check_explicit_specialization): Adjust error.
From-SVN: r215226
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/decl.c | 26 | ||||
-rw-r--r-- | gcc/cp/pt.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/var-templ11.C | 67 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.robertl/eb103.C | 2 |
5 files changed, 91 insertions, 13 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index afefed4..3e9cb89 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2014-09-11 Jason Merrill <jason@redhat.com> + + PR c++/63201 + * decl.c (start_decl): Handle specialization of member variable + template. + * pt.c (check_explicit_specialization): Adjust error. + 2014-09-11 Paolo Carlini <paolo.carlini@oracle.com> PR c++/61489 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6e195bb..59dada7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4659,20 +4659,24 @@ start_decl (const cp_declarator *declarator, if (field == NULL_TREE || !(VAR_P (field) || variable_template_p (field))) error ("%q+#D is not a static data member of %q#T", decl, context); - else + else if (variable_template_p (field) && !this_tmpl) { - if (variable_template_p (field)) + if (DECL_LANG_SPECIFIC (decl) + && DECL_TEMPLATE_SPECIALIZATION (decl)) + /* OK, specialization was already checked. */; + else { - if (!this_tmpl) - { - error_at (DECL_SOURCE_LOCATION (decl), - "non-member-template declaration of %qD", decl); - inform (DECL_SOURCE_LOCATION (field), "does not match " - "member template declaration here"); - return error_mark_node; - } - field = DECL_TEMPLATE_RESULT (field); + error_at (DECL_SOURCE_LOCATION (decl), + "non-member-template declaration of %qD", decl); + inform (DECL_SOURCE_LOCATION (field), "does not match " + "member template declaration here"); + return error_mark_node; } + } + else + { + if (variable_template_p (field)) + field = DECL_TEMPLATE_RESULT (field); if (DECL_CONTEXT (field) != context) { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 7f7ab93..008879b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2471,7 +2471,7 @@ check_explicit_specialization (tree declarator, template <class T> void f<int>(); */ if (uses_template_parms (declarator)) - error ("function template partial specialization %qD " + error ("non-type partial specialization %qD " "is not allowed", declarator); else error ("template-id %qD in declaration of primary template", diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ11.C b/gcc/testsuite/g++.dg/cpp1y/var-templ11.C new file mode 100644 index 0000000..5d6e0d0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/var-templ11.C @@ -0,0 +1,67 @@ +// PR c++/63201 +// { dg-do compile { target c++14 } } + +template <class T> +struct Y +{ + template <class U> static U x; +}; + +template <class T> +template <class U> +U Y<T>::x = U(); + +template <> +template <class U> +U Y<int>::x = 42; + +template <> +template <class U> +// odd diagnostic +U Y<float>::x<U> = 42; // { dg-error "partial specialization" } + +template <> +template <> +int Y<float>::x<int> = 42; // { dg-bogus "non-member-template declaration" } + +template <class T> +struct Z +{ + template <class U> struct ZZ + { + template <class V> static V x; + }; +}; + +template <class T> +template <class U> +template <class V> +V Z<T>::ZZ<U>::x = V(); + +template <> +template <> +template <class V> +V Z<int>::ZZ<int>::x = V(); + +template <> +template <class U> +struct Z<float>::ZZ +{ + template <class V> static V x; +}; + +template <> +template <class U> +template <class V> +V Z<float>::ZZ<U>::x = V(); + +template <> +template <> +template <> +int Z<float>::ZZ<int>::x<int> = 42; // { dg-bogus "non-member-template declaration" } + +int main() +{ + int y = Y<int>::x<int>; + int z = Z<float>::ZZ<int>::x<int>; +} diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb103.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb103.C index c272d94..ffc51ee 100644 --- a/gcc/testsuite/g++.old-deja/g++.robertl/eb103.C +++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb103.C @@ -4,7 +4,7 @@ template <int nlimb, int i> inline unsigned f (unsigned* ptr); template <int nlimb> -inline unsigned f<nlimb,nlimb> (unsigned* ptr) // { dg-error "function template partial specialization" } +inline unsigned f<nlimb,nlimb> (unsigned* ptr) // { dg-error "partial specialization" } { return 1; } |