+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
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)
{
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",
--- /dev/null
+// 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>;
+}
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;
}