aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-02-23 20:52:41 -0500
committerJason Merrill <jason@redhat.com>2020-02-24 08:58:31 -0500
commit32b8f5df9f05426c82c6de1acaf9ca4aec68039d (patch)
tree0fa257608ecfde18b590513c1f9d5f514f70d63e /gcc
parent120e873484f20d9a0b8400e2e464ac5b2088a747 (diff)
downloadgcc-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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c15
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/lambda-pack-init4.C10
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:&" }
+}