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" }
+    }
+};

Reply via email to