From 2b0a62741e675068c13e81690758855846c88726 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 13 Mar 2019 19:58:20 +0000 Subject: [PATCH] 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. From-SVN: r269659 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/parser.c | 20 ++++++++++++++--- gcc/testsuite/ChangeLog | 5 +++++ .../g++.dg/cpp2a/lambda-pack-init2.C | 22 +++++++++++++++++++ 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-pack-init2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2e06623efaf..fa0fdeae09f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -8,6 +8,10 @@ (cp_parser_constructor_declarator_p): Add FLAGS parameter. Pass it to cp_parser_type_specifier. + 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. + 2019-03-11 Jason Merrill PR c++/86521 - wrong overload resolution with ref-qualifiers. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8244366e669..14da1a14501 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10609,12 +10609,13 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) } bool init_pack_expansion = false; + location_t ellipsis_loc = UNKNOWN_LOCATION; if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) { - location_t loc = cp_lexer_peek_token (parser->lexer)->location; + ellipsis_loc = cp_lexer_peek_token (parser->lexer)->location; if (cxx_dialect < cxx2a) - pedwarn (loc, 0, "pack init-capture only available with " - "%<-std=c++2a%> or %<-std=gnu++2a%>"); + pedwarn (ellipsis_loc, 0, "pack init-capture only available with " + "%<-std=c++2a%> or %<-std=gnu++2a%>"); cp_lexer_consume_token (parser->lexer); init_pack_expansion = true; } @@ -10719,8 +10720,21 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) { + location_t loc = cp_lexer_peek_token (parser->lexer)->location; cp_lexer_consume_token (parser->lexer); capture_init_expr = make_pack_expansion (capture_init_expr); + if (init_pack_expansion) + { + /* If what follows is an initializer, the second '...' is + invalid. But for cases like [...xs...], the first one + is invalid. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_EQ) + || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN) + || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) + ellipsis_loc = loc; + error_at (ellipsis_loc, "too many %<...%> in lambda capture"); + continue; + } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index afb61b42d81..ed025c92267 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-03-13 Marek Polacek + + PR c++/89686 - mixing init-capture and simple-capture in lambda. + * g++.dg/cpp2a/lambda-pack-init2.C: New test. + 2019-03-13 Janus Weil PR fortran/89601 diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init2.C b/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init2.C new file mode 100644 index 00000000000..55d689dbc67 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init2.C @@ -0,0 +1,22 @@ +// PR c++/89686 +// { dg-do compile { target c++2a } } + +template +void foo(Ts... xs) +{ + int i = 10; + [...xs...]{}(); // { dg-error "4:too many ..... in lambda capture" } + [...xs...=xs]{}(); // { dg-error "9:too many ..... in lambda capture|expected" } + [xs...]{}(); + [...xs=xs]{}(); + + [i, ...xs...]{}(); // { dg-error "7:too many ..... in lambda capture" } + [i, ...xs...=xs]{}(); // { dg-error "12:too many ..... in lambda capture|expected" } + [i, xs...]{}(); + [i, ...xs=xs]{}(); +} + +int main() +{ + foo(0, 1, 2); +} -- 2.30.2