aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-02-01 13:44:41 -0500
committerJason Merrill <jason@gcc.gnu.org>2018-02-01 13:44:41 -0500
commitbfa28724748054a50075ce6f39b18c5ce111c73c (patch)
tree5e44dbeaafb2ae29a6c4461ab649a19da05c0c4b
parent6a92e0534b50ca5e97b325137044b502cceff99e (diff)
downloadgcc-bfa28724748054a50075ce6f39b18c5ce111c73c.zip
gcc-bfa28724748054a50075ce6f39b18c5ce111c73c.tar.gz
gcc-bfa28724748054a50075ce6f39b18c5ce111c73c.tar.bz2
PR c++/84126 - ICE with variadic generic lambda
PR c++/84036 PR c++/82249 * pt.c (tsubst_pack_expansion): Handle function parameter_packs in PACK_EXPANSION_EXTRA_ARGS. From-SVN: r257307
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/cp/pt.c38
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic9.C19
4 files changed, 68 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8fc9042..897774e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2018-02-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/84126 - ICE with variadic generic lambda
+ PR c++/84036
+ PR c++/82249
+ * pt.c (tsubst_pack_expansion): Handle function parameter_packs in
+ PACK_EXPANSION_EXTRA_ARGS.
+
2018-02-01 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/83796
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8983674..5f14e51 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3496,7 +3496,11 @@ extern void decl_shadowed_for_var_insert (tree, tree);
: &TYPE_MIN_VALUE_RAW (TYPE_PACK_EXPANSION_CHECK (NODE)))
/* Any additional template args to be applied when substituting into
- the pattern, set by tsubst_pack_expansion for partial instantiations. */
+ the pattern, set by tsubst_pack_expansion for partial instantiations.
+ If this is a TREE_LIST, the TREE_VALUE of the first element is the
+ usual template argument TREE_VEC, and the TREE_PURPOSE of later elements
+ are enclosing functions that provided function parameter packs we'll need
+ to map appropriately. */
#define PACK_EXPANSION_EXTRA_ARGS(NODE) \
*(TREE_CODE (NODE) == TYPE_PACK_EXPANSION \
? &TYPE_MAX_VALUE_RAW (NODE) \
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 9516be8..ca73bb1 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11439,7 +11439,20 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
pattern = PACK_EXPANSION_PATTERN (t);
/* Add in any args remembered from an earlier partial instantiation. */
- args = add_to_template_args (PACK_EXPANSION_EXTRA_ARGS (t), args);
+ tree extra = PACK_EXPANSION_EXTRA_ARGS (t);
+ if (extra && TREE_CODE (extra) == TREE_LIST)
+ {
+ /* The partial instantiation involved function parameter packs; map
+ from the general template to our current context. */
+ for (tree fns = TREE_CHAIN (extra); fns; fns = TREE_CHAIN (fns))
+ {
+ tree fn = TREE_PURPOSE (fns);
+ tree inst = enclosing_instantiation_of (fn);
+ register_parameter_specializations (fn, inst);
+ }
+ extra = TREE_VALUE (extra);
+ }
+ args = add_to_template_args (extra, args);
levels = TMPL_ARGS_DEPTH (args);
@@ -11610,7 +11623,28 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
have values for all the packs. So remember these until then. */
t = make_pack_expansion (pattern, complain);
- PACK_EXPANSION_EXTRA_ARGS (t) = args;
+ tree extra = args;
+ if (unsubstituted_fn_pack)
+ {
+ /* For function parameter packs it's more complicated; we need to
+ remember which enclosing function(s) provided them to this pack
+ expansion so we can map their parameters to the parameters of a
+ later full instantiation. */
+ tree fns = NULL_TREE;
+ for (tree p = packs; p; p = TREE_CHAIN (p))
+ {
+ tree parm = TREE_PURPOSE (p);
+ if (TREE_CODE (parm) != PARM_DECL)
+ continue;
+ parm = DECL_CONTEXT (parm);
+ if (purpose_member (parm, fns))
+ continue;
+ fns = tree_cons (parm, NULL_TREE, fns);
+ }
+ if (fns)
+ extra = tree_cons (NULL_TREE, extra, fns);
+ }
+ PACK_EXPANSION_EXTRA_ARGS (t) = extra;
return t;
}
else if (unsubstituted_packs)
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic9.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic9.C
new file mode 100644
index 0000000..1b3a644
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic9.C
@@ -0,0 +1,19 @@
+// PR c++/84126
+// { dg-do compile { target c++14 } }
+
+template <class... Ts>
+void sink(Ts...);
+
+template <typename T>
+int bar(T&); // ICE with reference, work with just T
+
+template <typename T >
+void foo(T){
+ [](auto ... k){
+ sink (bar(k) ...);
+ }(0);
+}
+
+int main() {
+ foo(0);
+}