Basically all we need to do here is accept it, like check_classfn; all the necessary checking was already done in check_explicit_specialization.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit f0ef26fb06fe5798cd7bb071a932a21cf5e5a878
Author: Jason Merrill <ja...@redhat.com>
Date:   Thu Sep 11 16:45:47 2014 -0400

    	PR c++/63201
    	* decl.c (start_decl): Handle specialization of member variable
    	template.
    	* pt.c (check_explicit_specialization): Adjust error.

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 if (variable_template_p (field) && !this_tmpl)
+	    {
+	      if (DECL_LANG_SPECIFIC (decl)
+		  && DECL_TEMPLATE_SPECIALIZATION (decl))
+		/* OK, specialization was already checked.  */;
+	      else
+		{
+		  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))
-		{
-		  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);
-		}
+		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;
 }

Reply via email to