As Barry explained in the PR, lambda capture is one of simple-capture ...[opt] ...[opt] init-capture
where init-capture requires an initializer. Here we have [...xs...] which is ill-formed as it's mingling both of these. Bootstrapped/regtested on x86_64-linux, ok for trunk? Or should I defer to GCC 10? 2019-03-12 Marek Polacek <pola...@redhat.com> PR c++/89686 - mixing init-capture and simple-capture in lambda. * parser.c (cp_parser_lambda_introducer): Give error when combining init-capture and simple-capture. * g++.dg/cpp2a/lambda-pack-init2.C: New test. diff --git gcc/cp/parser.c gcc/cp/parser.c index f95111169ed..d5d8f364752 100644 --- gcc/cp/parser.c +++ gcc/cp/parser.c @@ -10721,6 +10721,15 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) { cp_lexer_consume_token (parser->lexer); capture_init_expr = make_pack_expansion (capture_init_expr); + if (init_pack_expansion) + { + /* We'd already seen '...' so we were expecting an + init-capture. But we just saw another '...' which + would imply a simple-capture. */ + error_at (capture_token->location, + "combining init-capture and simple-capture"); + continue; + } } } diff --git gcc/testsuite/g++.dg/cpp2a/lambda-pack-init2.C gcc/testsuite/g++.dg/cpp2a/lambda-pack-init2.C new file mode 100644 index 00000000000..a6172076400 --- /dev/null +++ gcc/testsuite/g++.dg/cpp2a/lambda-pack-init2.C @@ -0,0 +1,19 @@ +// PR c++/89686 +// { dg-do compile { target c++2a } } + +template <typename... Ts> +void foo(Ts... xs) +{ + int i = 10; + [...xs...]{}(); // { dg-error "combining init-capture and simple-capture" } + [xs...]{}(); + [...xs=xs]{}(); + [i, ...xs...]{}(); // { dg-error "combining init-capture and simple-capture" } + [i, xs...]{}(); + [i, ...xs=xs]{}(); +} + +int main() +{ + foo(0, 1, 2); +}