aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-09-12 10:39:25 -0400
committerJason Merrill <jason@gcc.gnu.org>2014-09-12 10:39:25 -0400
commit4ee28eb7cea6ebf4713ad1f808d7e5e033ff508a (patch)
tree19910d805d5cb7cfa642612aea21ce5722033b73 /gcc
parentb6f866946b763415799331fe6799c4528357d6d0 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/cp/decl.c26
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/var-templ11.C67
-rw-r--r--gcc/testsuite/g++.old-deja/g++.robertl/eb103.C2
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;
}