diff options
author | Jason Merrill <jason@redhat.com> | 2020-02-23 20:52:41 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-02-24 08:58:31 -0500 |
commit | 32b8f5df9f05426c82c6de1acaf9ca4aec68039d (patch) | |
tree | 0fa257608ecfde18b590513c1f9d5f514f70d63e | |
parent | 120e873484f20d9a0b8400e2e464ac5b2088a747 (diff) | |
download | gcc-32b8f5df9f05426c82c6de1acaf9ca4aec68039d.zip gcc-32b8f5df9f05426c82c6de1acaf9ca4aec68039d.tar.gz gcc-32b8f5df9f05426c82c6de1acaf9ca4aec68039d.tar.bz2 |
c++: Fix C++20 variadic lambda init-capture grammar.
The grammar for variadic init-capture was fixed at the Prague C++ meeting
where we finalized C++20.
gcc/cp/ChangeLog
2020-02-24 Jason Merrill <jason@redhat.com>
P0780R2: Resolve lambda init-capture pack grammar.
* parser.c (cp_parser_lambda_introducer): Expect &...x=y rather than
...&x=y.
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/lambda-pack-init4.C | 10 |
3 files changed, 29 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8a3c9f7..cc0f42d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-02-24 Jason Merrill <jason@redhat.com> + + P0780R2: Resolve lambda init-capture pack grammar. + * parser.c (cp_parser_lambda_introducer): Expect &...x=y rather than + ...&x=y. + 2020-02-22 Marek Polacek <polacek@redhat.com> PR c++/93882 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index ee534b5..87ed2a3 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10620,6 +10620,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) /* Record default capture mode. "[&" "[=" "[&," "[=," */ if (cp_lexer_next_token_is (parser->lexer, CPP_AND) + && !cp_lexer_nth_token_is (parser->lexer, 2, CPP_ELLIPSIS) && !cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME) && !cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_THIS)) LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_REFERENCE; @@ -10715,6 +10716,13 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) continue; } + /* Remember whether we want to capture as a reference or not. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_AND)) + { + capture_kind = BY_REFERENCE; + cp_lexer_consume_token (parser->lexer); + } + bool init_pack_expansion = false; location_t ellipsis_loc = UNKNOWN_LOCATION; if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) @@ -10727,9 +10735,12 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) init_pack_expansion = true; } - /* Remember whether we want to capture as a reference or not. */ - if (cp_lexer_next_token_is (parser->lexer, CPP_AND)) + /* Early C++20 drafts had ...& instead of &...; be forgiving. */ + if (init_pack_expansion && capture_kind != BY_REFERENCE + && cp_lexer_next_token_is (parser->lexer, CPP_AND)) { + pedwarn (cp_lexer_peek_token (parser->lexer)->location, + 0, "%<&%> should come before %<...%>"); capture_kind = BY_REFERENCE; cp_lexer_consume_token (parser->lexer); } diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init4.C b/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init4.C new file mode 100644 index 0000000..e7c815b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-pack-init4.C @@ -0,0 +1,10 @@ +// P2095R0 +// { dg-do compile { target c++2a } } +// { dg-options "" } + +template <class... T> +void f(T... t) +{ + [&...x=t]{}; + [...&x=t]{}; // { dg-warning "7:&" } +} |