aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-11-03 20:51:41 +0000
committerJason Merrill <jason@redhat.com>2015-11-03 20:51:41 +0000
commitc91aae83ec94dd00271e00505695bdff77cc855a (patch)
tree25bec5d6f31db0f90246460e71c9e5aebde17d8b
parentb8793dd4b7f04d4052df6530d95f2cdd87bfba8c (diff)
Handle auto parameter packs.
* 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@229722 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/pt.c13
-rw-r--r--gcc/testsuite/g++.dg/concepts/auto3.C12
3 files changed, 33 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 884da0fb5f0..86c3653aff6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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>
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e836ec747d0..bc1ba2f38d8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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
index 00000000000..1cface77d55
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/auto3.C
@@ -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 "" }