My patch for 63809 fixed non-capturing use of a parameter pack in a
regular lambda, but not in a generic lambda, where we can't rely on
being instantiated within the enclosing context. So we use the existing
support for references to parameters from trailing return type, another
situation where we have a reference to a pack from unevaluated context
and don't have a local_specialization to help us.
With this change, my patch to copy the local_specializations table is no
longer needed, so I'm reverting it (but leaving the hash table copy
constructors).
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 46101839657233781f6fc9e824971cfbf8202a1e
Author: Jason Merrill <ja...@redhat.com>
Date: Tue Dec 15 16:43:02 2015 -0500
PR c++/63628
* pt.c (tsubst_pack_expansion): Also make dummy decls if
retrieve_local_specialization fails.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a45e6df..58742b0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10794,12 +10794,16 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
if (PACK_EXPANSION_LOCAL_P (t) || CONSTRAINT_VAR_P (parm_pack))
arg_pack = retrieve_local_specialization (parm_pack);
else
+ /* We can't rely on local_specializations for a parameter
+ name used later in a function declaration (such as in a
+ late-specified return type). Even if it exists, it might
+ have the wrong value for a recursive call. */
+ need_local_specializations = true;
+
+ if (!arg_pack)
{
- /* We can't rely on local_specializations for a parameter
- name used later in a function declaration (such as in a
- late-specified return type). Even if it exists, it might
- have the wrong value for a recursive call. Just make a
- dummy decl, since it's only used for its type. */
+ /* This parameter pack was used in an unevaluated context. Just
+ make a dummy decl, since it's only used for its type. */
arg_pack = tsubst_decl (parm_pack, args, complain);
if (arg_pack && DECL_PACK_P (arg_pack))
/* Partial instantiation of the parm_pack, we can't build
@@ -10807,7 +10811,6 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
arg_pack = NULL_TREE;
else
arg_pack = make_fnparm_pack (arg_pack);
- need_local_specializations = true;
}
}
else if (TREE_CODE (parm_pack) == FIELD_DECL)
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic3.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic3.C
new file mode 100644
index 0000000..9b3455a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic3.C
@@ -0,0 +1,15 @@
+// PR c++/63628
+// { dg-do compile { target c++14 } }
+
+auto const pack = [](auto&&... t)
+{
+ return [&](auto&& f)->decltype(auto)
+ {
+ return f(static_cast<decltype(t)>(t)...);
+ };
+};
+
+int main(int argc, char** argv) {
+ pack(1)([](int){});
+ return 0;
+}