From 22f6d174419e0649315049f5e2aec4b9a90e6ddc Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 12 Jun 2019 22:41:35 +0000 Subject: [PATCH] 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. From-SVN: r272223 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/parser.c | 14 +++++++++++++- gcc/testsuite/ChangeLog | 5 ++++- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this21.C | 10 ++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this21.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 87ca00bcf79..37d2b2a3fe8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2019-06-12 Marek Polacek + 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. + PR c++/90825 - endless recursion when evaluating sizeof. PR c++/90832 - endless recursion when evaluating sizeof. * constexpr.c (cxx_eval_constant_expression): Don't recurse on the diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e699fbc6b25..8f5ae84670a 100644 --- a/gcc/cp/parser.c +++ b/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, + "% 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 a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 05802734f6e..1c49ab9f7d5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,4 +1,7 @@ -2019-06-11 Marek Polacek +2019-06-12 Marek Polacek + + PR c++/66999 - 'this' captured by reference. + * g++.dg/cpp0x/lambda/lambda-this21.C: New test. PR c++/90825 - endless recursion when evaluating sizeof. PR c++/90832 - endless recursion when evaluating sizeof. diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this21.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this21.C new file mode 100644 index 00000000000..538dd375362 --- /dev/null +++ b/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" } + } +}; -- 2.30.2