pt.c (check_explicit_specialization): Don't complain about non-template variable.
authorJason Merrill <jason@redhat.com>
Tue, 26 Aug 2014 02:47:42 +0000 (22:47 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 26 Aug 2014 02:47:42 +0000 (22:47 -0400)
* pt.c (check_explicit_specialization): Don't complain about
non-template variable.
(template_for_substitution): Allow variable templates.
(check_template_variable): Fix logic for member var template.
* decl.c (start_decl): Don't complain about extra template header
here.

From-SVN: r214487

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

index d9bf9058f7e6b4b74e3cbc294f431a30448c0520..04394c31ab6b232d6b1030cb8c21ac8689c55130 100644 (file)
@@ -1,5 +1,12 @@
 2014-08-25  Jason Merrill  <jason@redhat.com>
 
+       * pt.c (check_explicit_specialization): Don't complain about
+       non-template variable.
+       (template_for_substitution): Allow variable templates.
+       (check_template_variable): Fix logic for member var template.
+       * decl.c (start_decl): Don't complain about extra template header
+       here.
+
        * decl.c (start_decl): Look through member variable template.
        * pt.c (tsubst_decl) [VAR_DECL]: Handle member variable templates.
        * decl2.c (grokfield): Set DECL_CONTEXT earlier on
index 80696ddb21651b4d34b7c8807c87aed880169471..d03f8a4707e594e6d836833c4197d1ec55e38960 100644 (file)
@@ -4672,14 +4672,6 @@ start_decl (const cp_declarator *declarator,
                    }
                  field = DECL_TEMPLATE_RESULT (field);
                }
-             else if (this_tmpl)
-               {
-                 error_at (DECL_SOURCE_LOCATION (decl),
-                           "member template declaration of %qD", decl);
-                 inform (DECL_SOURCE_LOCATION (field), "does not match "
-                         "non-member-template declaration here");
-                 return error_mark_node;
-               }
 
              if (DECL_CONTEXT (field) != context)
                {
index 3e6d777e72de0ba5d61a967d130f6abf539e648d..59df38722a8f672081b80b114b10a0151d6bed84 100644 (file)
@@ -2308,7 +2308,8 @@ check_template_variable (tree decl)
 {
   tree ctx = CP_DECL_CONTEXT (decl);
   int wanted = num_template_headers_for_class (ctx);
-  if (!TYPE_P (ctx) || !CLASSTYPE_TEMPLATE_INFO (ctx))
+  if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
+      && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
     {
       if (cxx_dialect < cxx14)
         pedwarn (DECL_SOURCE_LOCATION (decl), 0,
@@ -2323,7 +2324,8 @@ check_template_variable (tree decl)
       bool warned = pedwarn (DECL_SOURCE_LOCATION (decl), 0,
                             "too many template headers for %D (should be %d)",
                             decl, wanted);
-      if (warned && CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx))
+      if (warned && CLASS_TYPE_P (ctx)
+         && CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx))
        inform (DECL_SOURCE_LOCATION (decl),
                "members of an explicitly specialized class are defined "
                "without a template header");
@@ -2451,11 +2453,9 @@ check_explicit_specialization (tree declarator,
       /* Fall through.  */
     case tsk_expl_spec:
       if (VAR_P (decl) && TREE_CODE (declarator) != TEMPLATE_ID_EXPR)
-        {
-           // In cases like template<> constexpr bool v = true;
-           error ("%qD is not a template variable", dname);
-           break;
-        }
+       /* In cases like template<> constexpr bool v = true;
+          We'll give an error in check_template_variable.  */
+       break;
 
       SET_DECL_TEMPLATE_SPECIALIZATION (decl);
       if (ctype)
@@ -19711,8 +19711,6 @@ template_for_substitution (tree decl)
         cannot restructure the loop to just keep going until we find
         a template with a definition, since that might go too far if
         a specialization was declared, but not defined.  */
-      gcc_assert (!VAR_P (decl)
-                 || DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (tmpl)));
 
       /* Fetch the more general template.  */
       tmpl = DECL_TI_TEMPLATE (tmpl);
diff --git a/gcc/testsuite/g++.dg/cpp1y/var-templ10.C b/gcc/testsuite/g++.dg/cpp1y/var-templ10.C
new file mode 100644 (file)
index 0000000..ece2eb2
--- /dev/null
@@ -0,0 +1,16 @@
+// { 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();
+
+int main()
+{
+  int y = Y<int>::x<int>;
+}