diff options
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 81aff35..c669e49 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10547,6 +10547,8 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) error ("non-local lambda expression cannot have a capture-default"); } + hash_set<tree, true> ids; + tree first_capture_id = NULL_TREE; while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_SQUARE)) { cp_token* capture_token; @@ -10582,11 +10584,14 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) pedwarn (loc, 0, "explicit by-copy capture of %<this%> redundant " "with by-copy capture default"); cp_lexer_consume_token (parser->lexer); - add_capture (lambda_expr, - /*id=*/this_identifier, - /*initializer=*/finish_this_expr (), - /*by_reference_p=*/true, - explicit_init_p); + if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr)) + pedwarn (input_location, 0, + "already captured %qD in lambda expression", + this_identifier); + else + add_capture (lambda_expr, /*id=*/this_identifier, + /*initializer=*/finish_this_expr (), + /*by_reference_p=*/true, explicit_init_p); continue; } @@ -10600,11 +10605,14 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) "%<-std=c++17%> or %<-std=gnu++17%>"); cp_lexer_consume_token (parser->lexer); cp_lexer_consume_token (parser->lexer); - add_capture (lambda_expr, - /*id=*/this_identifier, - /*initializer=*/finish_this_expr (), - /*by_reference_p=*/false, - explicit_init_p); + if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr)) + pedwarn (input_location, 0, + "already captured %qD in lambda expression", + this_identifier); + else + add_capture (lambda_expr, /*id=*/this_identifier, + /*initializer=*/finish_this_expr (), + /*by_reference_p=*/false, explicit_init_p); continue; } @@ -10753,11 +10761,28 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) "default", capture_id); } - add_capture (lambda_expr, - capture_id, - capture_init_expr, - /*by_reference_p=*/capture_kind == BY_REFERENCE, - explicit_init_p); + /* Check for duplicates. + Optimize for the zero or one explicit captures cases and only create + the hash_set after adding second capture. */ + bool found = false; + if (ids.elements ()) + found = ids.add (capture_id); + else if (first_capture_id == NULL_TREE) + first_capture_id = capture_id; + else if (capture_id == first_capture_id) + found = true; + else + { + ids.add (first_capture_id); + ids.add (capture_id); + } + if (found) + pedwarn (input_location, 0, + "already captured %qD in lambda expression", capture_id); + else + add_capture (lambda_expr, capture_id, capture_init_expr, + /*by_reference_p=*/capture_kind == BY_REFERENCE, + explicit_init_p); /* If there is any qualification still in effect, clear it now; we will be starting fresh with the next capture. */ |