PR c++/71569 - ICE with redundant args on member variable template.
authorJason Merrill <jason@redhat.com>
Thu, 1 Mar 2018 16:00:34 +0000 (11:00 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 1 Mar 2018 16:00:34 +0000 (11:00 -0500)
* decl.c (start_decl): Handle partial specialization of member
variable template.
* pt.c (determine_specialization): Allow partial specialization
of member variable template without specializing enclosing class.
(process_partial_specialization): Improve error message.

Co-Authored-By: Alexandre Oliva <aoliva@redhat.com>
From-SVN: r258102

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp1y/var-templ58.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/var-templ58a.C [new file with mode: 0644]

index be9b3fd..a6deacb 100644 (file)
@@ -1,3 +1,13 @@
+2018-03-01  Jason Merrill  <jason@redhat.com>
+           Alexandre Oliva <aoliva@redhat.com>
+
+       PR c++/71569 - ICE with redundant args on member variable template.
+       * decl.c (start_decl): Handle partial specialization of member
+       variable template.
+       * pt.c (determine_specialization): Allow partial specialization
+       of member variable template without specializing enclosing class.
+       (process_partial_specialization): Improve error message.
+
 2018-02-28  Jason Merrill  <jason@redhat.com>
 
        PR c++/71784 - ICE with ref-qualifier and explicit specialization.
index f1be229..db64d12 100644 (file)
@@ -5080,19 +5080,17 @@ 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)
+                  && (DECL_LANG_SPECIFIC (decl)
+                      && DECL_TEMPLATE_SPECIALIZATION (decl)))
+           /* OK, specialization was already checked.  */;
          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;
-               }
+             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
            {
index 7345119..e07d77b 100644 (file)
@@ -2060,7 +2060,8 @@ determine_specialization (tree template_id,
   /* We shouldn't be specializing a member template of an
      unspecialized class template; we already gave an error in
      check_specialization_scope, now avoid crashing.  */
-  if (template_count && DECL_CLASS_SCOPE_P (decl)
+  if (!VAR_P (decl)
+      && template_count && DECL_CLASS_SCOPE_P (decl)
       && template_class_depth (DECL_CONTEXT (decl)) > 0)
     {
       gcc_assert (errorcount);
@@ -4840,10 +4841,13 @@ process_partial_specialization (tree decl)
     {
       if (!flag_concepts)
         error ("partial specialization %q+D does not specialize "
-              "any template arguments", decl);
+              "any template arguments; to define the primary template, "
+              "remove the template argument list", decl);
       else
         error ("partial specialization %q+D does not specialize any "
-              "template arguments and is not more constrained than", decl);
+              "template arguments and is not more constrained than "
+              "the primary template; to define the primary template, "
+              "remove the template argument list", decl);
       inform (DECL_SOURCE_LOCATION (maintmpl), "primary template here");
     }
 
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ58.C b/gcc/testsuite/g++.dg/cpp1y/var-templ58.C
new file mode 100644 (file)
index 0000000..f9095f6
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/71569
+// { dg-do compile { target c++14 } }
+
+template <class T>
+struct A {
+  template <class U>
+  static const U u;
+};
+
+template <class T>
+template <class U>
+const U A<T>::u<U> = 0;        // { dg-error "does not specialize" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ58a.C b/gcc/testsuite/g++.dg/cpp1y/var-templ58a.C
new file mode 100644 (file)
index 0000000..850a2c9
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/71569
+// { dg-do compile { target c++14 } }
+
+template <class T>
+struct A {
+  template <class U>
+  static const U u;
+};
+
+template <class T>
+template <class U>
+const U* A<T>::u<U*> = 0;
+
+const int *p = A<char>::u<int*>;