We parse the initializer for an init-capture as an initializer, which checks for any unexpanded parameter packs. Normally we avoid that error in a lambda by checking whether we're in a lambda, but at this point we haven't entered the lambda scope yet.
Jakub, if we end up needing an RC3 it would be nice to get this into 8.1, but if not it's fine to wait for 8.2. Tested x86_64-pc-linux-gnu, applying to trunk.
commit 2009e6d79c38c4867600156ab6b457c0e664927f Author: Jason Merrill <ja...@redhat.com> Date: Mon Apr 30 13:33:12 2018 -0400 PR c++/85305 - pack in lambda init-capture. * parser.c (cp_parser_initializer): Add subexpression_p parm; don't check_for_bare_parameter_packs in a subexpression. (cp_parser_lambda_introducer): Use it. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d8ce28a6d61..b839232bcbe 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2243,7 +2243,7 @@ static tree cp_parser_default_argument static void cp_parser_function_body (cp_parser *, bool); static tree cp_parser_initializer - (cp_parser *, bool *, bool *); + (cp_parser *, bool *, bool *, bool = false); static cp_expr cp_parser_initializer_clause (cp_parser *, bool *); static cp_expr cp_parser_braced_list @@ -10358,7 +10358,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) "lambda capture initializers " "only available with -std=c++14 or -std=gnu++14"); capture_init_expr = cp_parser_initializer (parser, &direct, - &non_constant); + &non_constant, true); explicit_init_p = true; if (capture_init_expr == NULL_TREE) { @@ -21860,7 +21860,7 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser, static tree cp_parser_initializer (cp_parser* parser, bool* is_direct_init, - bool* non_constant_p) + bool* non_constant_p, bool subexpression_p) { cp_token *token; tree init; @@ -21907,7 +21907,7 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init, init = error_mark_node; } - if (check_for_bare_parameter_packs (init)) + if (!subexpression_p && check_for_bare_parameter_packs (init)) init = error_mark_node; return init; diff --git a/gcc/testsuite/g++.dg/cpp1z/fold-lambda2.C b/gcc/testsuite/g++.dg/cpp1z/fold-lambda2.C new file mode 100644 index 00000000000..e93f55f7fd8 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/fold-lambda2.C @@ -0,0 +1,8 @@ +// PR c++/85305 +// { dg-additional-options -std=c++17 } + +template <int... Is> +void foo() +{ + ([i = Is]{}(), ...); +}