]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/34052 (Trouble with variadic templates as template-template parameter)
authorDouglas Gregor <doug.gregor@gmail.com>
Tue, 15 Jan 2008 16:06:48 +0000 (16:06 +0000)
committerDoug Gregor <dgregor@gcc.gnu.org>
Tue, 15 Jan 2008 16:06:48 +0000 (16:06 +0000)
2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>

       PR c++/34052
       * pt.c (check_default_tmpl_args): Check for parameter packs that
       aren't at the end of a primary template.
       (push_template_decl_real): Remove check for parameter packs that
       aren't at the end of a primary template; that now happens in
       check_default_tmpl_args.
       * semantics.c (finish_template_template_parm): Use
       check_default_tmpl_args to check for errors in the template
       parameter list.

2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>

       PR c++/34052
       * g++.dg/cpp0x/vt-34052.C: New.
       * g++.dg/template/ttp26.C: New.

From-SVN: r131543

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/vt-34052.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/ttp26.C [new file with mode: 0644]

index c46c07251a4552dc188174993ca256b3a5d18d10..4125ade97577ebf147a86d7ead3c1859dd7a64a9 100644 (file)
@@ -1,3 +1,15 @@
+2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>
+
+       PR c++/34052
+       * pt.c (check_default_tmpl_args): Check for parameter packs that
+       aren't at the end of a primary template.
+       (push_template_decl_real): Remove check for parameter packs that
+       aren't at the end of a primary template; that now happens in
+       check_default_tmpl_args.
+       * semantics.c (finish_template_template_parm): Use
+       check_default_tmpl_args to check for errors in the template
+       parameter list.
+       
 2008-01-12  Doug Kwan  <dougkwan@google.com>
 
        * decl.c: (grokdeclarator): Use OPT_Wignored_qualifiers
index f25f2c403049143eeba64fb8da4bc256607183a0..b9c40b209b10a35bb5d22c01a9778864c5cf3517 100644 (file)
@@ -3537,10 +3537,11 @@ process_partial_specialization (tree decl)
   return decl;
 }
 
-/* Check that a template declaration's use of default arguments is not
-   invalid.  Here, PARMS are the template parameters.  IS_PRIMARY is
-   nonzero if DECL is the thing declared by a primary template.
-   IS_PARTIAL is nonzero if DECL is a partial specialization.
+/* Check that a template declaration's use of default arguments and
+   parameter packs is not invalid.  Here, PARMS are the template
+   parameters.  IS_PRIMARY is nonzero if DECL is the thing declared by
+   a primary template.  IS_PARTIAL is nonzero if DECL is a partial
+   specialization.
    
 
    IS_FRIEND_DECL is nonzero if DECL is a friend function template
@@ -3625,6 +3626,29 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary,
                   TREE_PURPOSE (parm) = error_mark_node;
                   no_errors = false;
                 }
+             else if (is_primary
+                      && !is_partial
+                      && !is_friend_decl
+                      && TREE_CODE (decl) == TYPE_DECL
+                      && i < ntparms - 1
+                      && template_parameter_pack_p (TREE_VALUE (parm)))
+               {
+                 /* A primary class template can only have one
+                    parameter pack, at the end of the template
+                    parameter list.  */
+
+                 if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL)
+                   error ("parameter pack %qE must be at the end of the"
+                          " template parameter list", TREE_VALUE (parm));
+                 else
+                   error ("parameter pack %qT must be at the end of the"
+                          " template parameter list", 
+                          TREE_TYPE (TREE_VALUE (parm)));
+
+                 TREE_VALUE (TREE_VEC_ELT (inner_parms, i)) 
+                   = error_mark_node;
+                 no_errors = false;
+               }
             }
         }
     }
@@ -3888,31 +3912,6 @@ push_template_decl_real (tree decl, bool is_friend)
   if (is_partial)
     return process_partial_specialization (decl);
 
-  /* A primary class template can only have one parameter pack, at the
-     end of the template parameter list.  */
-  if (primary && TREE_CODE (decl) == TYPE_DECL)
-    {
-      tree inner_parms 
-       = INNERMOST_TEMPLATE_PARMS (current_template_parms);
-      int i, len = TREE_VEC_LENGTH (inner_parms);
-      for (i = 0; i < len - 1; i++)
-        {
-          tree parm = TREE_VALUE (TREE_VEC_ELT (inner_parms, i));
-
-         if (template_parameter_pack_p (parm))
-           {
-             if (TREE_CODE (parm) == PARM_DECL)
-               error ("parameter pack %qE must be at the end of the"
-                      " template parameter list", parm);
-             else
-               error ("parameter pack %qT must be at the end of the"
-                      " template parameter list", TREE_TYPE (parm));
-
-             TREE_VALUE (TREE_VEC_ELT (inner_parms, i)) = error_mark_node;
-           }
-        }
-    }
-
   args = current_template_args ();
 
   if (!ctx
index 5df43d5ad16a55820086309bac9164119742cb1e..0e8c435dcc8bea46fec36e7cf39a7f56cdd07ada 100644 (file)
@@ -2191,6 +2191,10 @@ finish_template_template_parm (tree aggr, tree identifier)
 
   gcc_assert (DECL_TEMPLATE_PARMS (tmpl));
 
+  check_default_tmpl_args (decl, DECL_TEMPLATE_PARMS (tmpl), 
+                          /*is_primary=*/true, /*is_partial=*/false,
+                          /*is_friend=*/0);
+
   return finish_template_type_parm (aggr, tmpl);
 }
 
index ac27643aeea6c68f47dc080e0eb939c59b1a3143..7aef4010b2828a990df6fbf00fa0b46b32778745 100644 (file)
@@ -1,3 +1,9 @@
+2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>
+
+       PR c++/34052
+       * g++.dg/cpp0x/vt-34052.C: New.
+       * g++.dg/template/ttp26.C: New.
+       
 2008-01-14  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/rep_clause2.ad[sb]: New test.
diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-34052.C b/gcc/testsuite/g++.dg/cpp0x/vt-34052.C
new file mode 100644 (file)
index 0000000..15310cf
--- /dev/null
@@ -0,0 +1,8 @@
+// { dg-options "-std=c++0x" }
+template<typename... T, typename = T> struct A {}; // { dg-error "must be at the end" }
+
+
+template<template<typename... T, typename = T> class U> struct B // { dg-error "must be at the end" }
+{
+  template<int> U<int> foo(); // { dg-error "mismatch|constant|invalid|invalid" }
+};
diff --git a/gcc/testsuite/g++.dg/template/ttp26.C b/gcc/testsuite/g++.dg/template/ttp26.C
new file mode 100644 (file)
index 0000000..6ba5cb2
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c++/34052
+template<typename T = int, typename U> class C; // { dg-error "no default argument" }
+
+template<template<typename T = int, typename U> class C> struct X; // { dg-error "no default argument" }
+