PR c++/66999 - 'this' captured by reference.
authorMarek Polacek <polacek@redhat.com>
Wed, 12 Jun 2019 22:41:35 +0000 (22:41 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 12 Jun 2019 22:41:35 +0000 (22:41 +0000)
* 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
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-this21.C [new file with mode: 0644]

index 87ca00bcf79254d00f150c5b9e14da73b4d153a0..37d2b2a3fe8f51adeb50315a4b391b702141c60a 100644 (file)
@@ -1,5 +1,9 @@
 2019-06-12  Marek Polacek  <polacek@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.
+
        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
index e699fbc6b2564ce111a08d7d011b7250c24f53b4..8f5ae84670aa01ce1709fb343e8f4f9f97c3945b 100644 (file)
@@ -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))
index 05802734f6e04f7792f543775221f5d81d167497..1c49ab9f7d5cb379e19f0c721375a6cea5cda899 100644 (file)
@@ -1,4 +1,7 @@
-2019-06-11  Marek Polacek  <polacek@redhat.com>
+2019-06-12  Marek Polacek  <polacek@redhat.com>
+
+       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 (file)
index 0000000..538dd37
--- /dev/null
@@ -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" }
+    }
+};