Handle auto parameter packs.
authorJason Merrill <jason@redhat.com>
Tue, 3 Nov 2015 20:51:41 +0000 (15:51 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 3 Nov 2015 20:51:41 +0000 (15:51 -0500)
* pt.c (struct find_parameter_pack_data): Add
type_pack_expansion_p field.
(find_parameter_packs_r): Use it to turn 'auto' into a parameter pack.
(uses_parameter_packs, make_pack_expansion)
(check_for_bare_parameter_packs, fixed_parameter_pack_p): Set it.

From-SVN: r229722

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/concepts/auto3.C [new file with mode: 0644]

index 884da0fb5f00ac3b69ad676231e62258b55668e6..86c3653aff6b6bb524773c9b4d6abe014866489e 100644 (file)
@@ -1,3 +1,11 @@
+2015-11-03  Jason Merrill  <jason@redhat.com>
+
+       * pt.c (struct find_parameter_pack_data): Add
+       type_pack_expansion_p field.
+       (find_parameter_packs_r): Use it to turn 'auto' into a parameter pack.
+       (uses_parameter_packs, make_pack_expansion)
+       (check_for_bare_parameter_packs, fixed_parameter_pack_p): Set it.
+
 2015-11-03  Thomas Schwinge  <thomas@codesourcery.com>
            Chung-Lin Tang  <cltang@codesourcery.com>
 
index e836ec747d03a4393b0efb9ba13e1de86ed25e6a..bc1ba2f38d870a7c7455894968e29d6232883391 100644 (file)
@@ -3407,6 +3407,9 @@ struct find_parameter_pack_data
 
   /* Set of AST nodes that have been visited by the traversal.  */
   hash_set<tree> *visited;
+
+  /* True iff we're making a type pack expansion.  */
+  bool type_pack_expansion_p;
 };
 
 /* Identifies all of the argument packs that occur in a template
@@ -3443,6 +3446,12 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
     case TEMPLATE_TYPE_PARM:
       t = TYPE_MAIN_VARIANT (t);
     case TEMPLATE_TEMPLATE_PARM:
+      /* If the placeholder appears in the decl-specifier-seq of a function
+        parameter pack (14.6.3), or the type-specifier-seq of a type-id that
+        is a pack expansion, the invented template parameter is a template
+        parameter pack.  */
+      if (ppd->type_pack_expansion_p && is_auto_or_concept (t))
+       TEMPLATE_TYPE_PARAMETER_PACK (t) = true;
       if (TEMPLATE_TYPE_PARAMETER_PACK (t))
         parameter_pack_p = true;
       break;
@@ -3577,6 +3586,7 @@ uses_parameter_packs (tree t)
   struct find_parameter_pack_data ppd;
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = new hash_set<tree>;
+  ppd.type_pack_expansion_p = false;
   cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
   delete ppd.visited;
   return parameter_packs != NULL_TREE;
@@ -3686,6 +3696,7 @@ make_pack_expansion (tree arg)
   /* Determine which parameter packs will be expanded.  */
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = new hash_set<tree>;
+  ppd.type_pack_expansion_p = TYPE_P (arg);
   cp_walk_tree (&arg, &find_parameter_packs_r, &ppd, ppd.visited);
   delete ppd.visited;
 
@@ -3733,6 +3744,7 @@ check_for_bare_parameter_packs (tree t)
 
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = new hash_set<tree>;
+  ppd.type_pack_expansion_p = false;
   cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
   delete ppd.visited;
 
@@ -4772,6 +4784,7 @@ fixed_parameter_pack_p (tree parm)
   struct find_parameter_pack_data ppd;
   ppd.parameter_packs = &parameter_packs;
   ppd.visited = new hash_set<tree>;
+  ppd.type_pack_expansion_p = false;
 
   fixed_parameter_pack_p_1 (parm, &ppd);
 
diff --git a/gcc/testsuite/g++.dg/concepts/auto3.C b/gcc/testsuite/g++.dg/concepts/auto3.C
new file mode 100644 (file)
index 0000000..1cface7
--- /dev/null
@@ -0,0 +1,12 @@
+// { dg-options -std=c++1z }
+
+template <class...> class tuple {};
+
+tuple<int> t;
+tuple<auto> y = t;
+
+tuple<int,double> t2;
+tuple<auto...> x = t2;
+tuple<auto...> x2 = t;
+
+tuple<auto> y2 = t2;           // { dg-error "" }