PR c++/60033 * pt.c (retrieve_specialization): When retrieving a capture pack from a generic lambda, remove the lambda's own template argument list prior to fetching the specialization.
PR c++/60033 * g++.dg/cpp1y/pr60033.C: New testcase. --- gcc/cp/pt.c | 11 +++++++++++ gcc/testsuite/g++.dg/cpp1y/pr60033.C | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1y/pr60033.C diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8126905..0d0b1dc 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1031,6 +1031,17 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash) gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL || TREE_CODE (tmpl) == FIELD_DECL); + /* When retrieving a capture pack from a generic lambda, remove the lambda + call op's own template argument list from ARGS. Only the template + arguments active for the closure type should be used to retrieve the pack + specialization. + XXX: It may be that this situation can be avoided by manipulating the field + XXX: type earlier. */ + if (TREE_CODE (tmpl) == FIELD_DECL + && LAMBDA_FUNCTION_P (current_function_decl) + && template_class_depth (DECL_CONTEXT (tmpl)) != TMPL_ARGS_DEPTH (args)) + args = strip_innermost_template_args (args, 1); + /* There should be as many levels of arguments as there are levels of parameters. */ gcc_assert (TMPL_ARGS_DEPTH (args) diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60033.C b/gcc/testsuite/g++.dg/cpp1y/pr60033.C new file mode 100644 index 0000000..8194bec --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/pr60033.C @@ -0,0 +1,20 @@ +// PR c++/60033 +// { dg-options -std=c++1y } + +template <typename... T> +auto f(T&&... ts) +{ + return sizeof...(ts); +} + +template <typename... T> +auto g(T&&... ts) { + return [&] (auto v) { + return f(ts...); + }; +} + +int main() +{ + return g(1,2,3,4)(5) == 4 ? 0 : 1; +} -- 1.9.0