This patch improves a diagnostic when parsing a lambda introducer; in particular, we should handle '&this' better than we currently do. clang/icc specifically point out that 'this' cannot be captured by reference, let's do the same.
Bootstrapped/regtested on x86_64-linux, ok for trunk? 2019-06-08 Marek Polacek <pola...@redhat.com> PR c++/66999 - 'this' captured by reference. * parser.c (cp_parser_lambda_introducer): Reject `&this'. Use cp_lexer_nth_token_is instead of cp_lexer_peek_nth_token. * g++.dg/cpp0x/lambda/lambda-this21.C: New test. diff --git gcc/cp/parser.c gcc/cp/parser.c index 308b2d4ad70..74796e197fe 100644 --- gcc/cp/parser.c +++ gcc/cp/parser.c @@ -10526,7 +10526,8 @@ 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_peek_nth_token (parser->lexer, 2)->type != CPP_NAME) + && !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; else if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_COPY; @@ -10609,6 +10610,17 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) continue; } + /* But reject `&this'. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_AND) + && cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_THIS)) + { + error_at (cp_lexer_peek_token (parser->lexer)->location, + "%<this%> cannot be captured by reference"); + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + continue; + } + bool init_pack_expansion = false; location_t ellipsis_loc = UNKNOWN_LOCATION; if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)) diff --git gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this21.C gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this21.C new file mode 100644 index 00000000000..a3256b5700f --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this21.C @@ -0,0 +1,10 @@ +// PR c++/66999 - 'this' captured by reference. +// { dg-do compile { target c++11 } } + +struct X { + void bar (int n) + { + auto l1 = [&this] { }; // { dg-error ".this. cannot be captured by reference" } + auto l2 = [=, &this] { }; // { dg-error ".this. cannot be captured by reference" } + } +};