P0806R2 - Deprecate implicit capture of this via [=]
authorMarek Polacek <polacek@redhat.com>
Mon, 13 Aug 2018 15:46:42 +0000 (15:46 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Mon, 13 Aug 2018 15:46:42 +0000 (15:46 +0000)
P0806R2 - Deprecate implicit capture of this via [=]
* lambda.c (add_default_capture): Formatting fixes.  Warn about
deprecated implicit capture of this via [=].

* g++.dg/cpp2a/lambda-this1.C: New test.
* g++.dg/cpp2a/lambda-this2.C: New test.
* g++.dg/cpp2a/lambda-this3.C: New test.

From-SVN: r263508

gcc/cp/ChangeLog
gcc/cp/lambda.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp2a/lambda-this1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/lambda-this2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/lambda-this3.C [new file with mode: 0644]

index 859085be4cad94fc32954ff7ed2dff8dfbf70378..da6703b304c16e2827db5e5911a7fbff85b1d3a4 100644 (file)
@@ -1,5 +1,9 @@
 2018-08-13  Marek Polacek  <polacek@redhat.com>
 
+       P0806R2 - Deprecate implicit capture of this via [=]
+       * lambda.c (add_default_capture): Formatting fixes.  Warn about
+       deprecated implicit capture of this via [=].
+
        PR c++/86915
        * decl.c (create_array_type_for_decl): Handle null name.
 
index 54fc3ee85c30691d204bafd293e39159f33c7ccb..25a4d6f7eef4c5bbd727e7b2ef86b8a1e038b185 100644 (file)
@@ -695,14 +695,10 @@ tree
 add_default_capture (tree lambda_stack, tree id, tree initializer)
 {
   bool this_capture_p = (id == this_identifier);
-
   tree var = NULL_TREE;
-
   tree saved_class_type = current_class_type;
 
-  tree node;
-
-  for (node = lambda_stack;
+  for (tree node = lambda_stack;
        node;
        node = TREE_CHAIN (node))
     {
@@ -720,6 +716,19 @@ add_default_capture (tree lambda_stack, tree id, tree initializer)
                                 == CPLD_REFERENCE)),
                            /*explicit_init_p=*/false);
       initializer = convert_from_reference (var);
+
+      /* Warn about deprecated implicit capture of this via [=].  */
+      if (cxx_dialect >= cxx2a
+         && this_capture_p
+         && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) == CPLD_COPY
+         && !in_system_header_at (LAMBDA_EXPR_LOCATION (lambda)))
+       {
+         if (warning_at (LAMBDA_EXPR_LOCATION (lambda), OPT_Wdeprecated,
+                         "implicit capture of %qE via %<[=]%> is deprecated "
+                         "in C++20", this_identifier))
+           inform (LAMBDA_EXPR_LOCATION (lambda), "add explicit %<this%> or "
+                   "%<*this%> capture");
+       }
     }
 
   current_class_type = saved_class_type;
index c11b5c89af11fb7454453ac8a5aef60afcf6b134..d7ed84edacfcc72b989195e60ccbdc4410ec7968 100644 (file)
@@ -1,3 +1,10 @@
+2018-08-13  Marek Polacek  <polacek@redhat.com>
+
+       P0806R2 - Deprecate implicit capture of this via [=]
+       * g++.dg/cpp2a/lambda-this1.C: New test.
+       * g++.dg/cpp2a/lambda-this2.C: New test.
+       * g++.dg/cpp2a/lambda-this3.C: New test.
+
 2018-08-13  Marek Polacek  <polacek@redhat.com>
 
        PR c++/86915
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-this1.C b/gcc/testsuite/g++.dg/cpp2a/lambda-this1.C
new file mode 100644 (file)
index 0000000..a31b968
--- /dev/null
@@ -0,0 +1,51 @@
+// P0806R2
+// { dg-do compile }
+// { dg-options "-std=c++2a" }
+
+struct X {
+  int x;
+  void foo (int n) {
+    auto a1 = [=] { x = n; }; // { dg-warning "implicit capture" }
+    auto a2 = [=, this] { x = n; };
+    auto a3 = [=, *this]() mutable { x = n; };
+    auto a4 = [&] { x = n; };
+    auto a5 = [&, this] { x = n; };
+    auto a6 = [&, *this]() mutable { x = n; };
+
+    auto a7 = [=] { // { dg-warning "implicit capture" }
+      auto a = [=] { // { dg-warning "implicit capture" }
+        auto a2 = [=] { x = n; }; // { dg-warning "implicit capture" }
+      };
+    };
+
+    auto a8 = [=, this] {
+      auto a = [=, this] {
+        auto a2 = [=, this] { x = n; };
+      };
+    };
+
+    auto a9 = [=, *this]() mutable {
+      auto a = [=, *this]() mutable {
+        auto a2 = [=, *this]() mutable { x = n; };
+      };
+    };
+
+    auto a10 = [&] {
+      auto a = [&] {
+        auto a2 = [&] { x = n; };
+      };
+    };
+
+    auto a11 = [&, this] {
+      auto a = [&, this] {
+        auto a2 = [&, this] { x = n; };
+      };
+    };
+
+    auto a12 = [&, *this]() mutable {
+      auto a = [&, *this]() mutable {
+        auto a2 = [&, *this]() mutable { x = n; };
+      };
+    };
+  }
+};
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-this2.C b/gcc/testsuite/g++.dg/cpp2a/lambda-this2.C
new file mode 100644 (file)
index 0000000..307fb4c
--- /dev/null
@@ -0,0 +1,51 @@
+// P0806R2
+// { dg-do compile }
+// { dg-options "-std=c++2a -Wno-deprecated" }
+
+struct X {
+  int x;
+  void foo (int n) {
+    auto a1 = [=] { x = n; }; // { dg-bogus "implicit capture" }
+    auto a2 = [=, this] { x = n; };
+    auto a3 = [=, *this]() mutable { x = n; };
+    auto a4 = [&] { x = n; };
+    auto a5 = [&, this] { x = n; };
+    auto a6 = [&, *this]() mutable { x = n; };
+
+    auto a7 = [=] { // { dg-bogus "implicit capture" }
+      auto a = [=] { // { dg-bogus "implicit capture" }
+        auto a2 = [=] { x = n; }; // { dg-bogus "implicit capture" }
+      };
+    };
+
+    auto a8 = [=, this] {
+      auto a = [=, this] {
+        auto a2 = [=, this] { x = n; };
+      };
+    };
+
+    auto a9 = [=, *this]() mutable {
+      auto a = [=, *this]() mutable {
+        auto a2 = [=, *this]() mutable { x = n; };
+      };
+    };
+
+    auto a10 = [&] {
+      auto a = [&] {
+        auto a2 = [&] { x = n; };
+      };
+    };
+
+    auto a11 = [&, this] {
+      auto a = [&, this] {
+        auto a2 = [&, this] { x = n; };
+      };
+    };
+
+    auto a12 = [&, *this]() mutable {
+      auto a = [&, *this]() mutable {
+        auto a2 = [&, *this]() mutable { x = n; };
+      };
+    };
+  }
+};
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-this3.C b/gcc/testsuite/g++.dg/cpp2a/lambda-this3.C
new file mode 100644 (file)
index 0000000..5e5c8b3
--- /dev/null
@@ -0,0 +1,55 @@
+// P0806R2
+// { dg-do compile }
+// { dg-options "-std=c++17" }
+
+struct X {
+  int x;
+  void foo (int n) {
+    auto a1 = [=] { x = n; }; // { dg-bogus "implicit capture" }
+    auto a2 = [=, this] { x = n; };
+    // { dg-warning "explicit by-copy capture" "" { target c++17_down } .-1 }
+    auto a3 = [=, *this]() mutable { x = n; };
+    auto a4 = [&] { x = n; };
+    auto a5 = [&, this] { x = n; };
+    auto a6 = [&, *this]() mutable { x = n; };
+
+    auto a7 = [=] { // { dg-bogus "implicit capture" }
+      auto a = [=] { // { dg-bogus "implicit capture" }
+        auto a2 = [=] { x = n; }; // { dg-bogus "implicit capture" }
+      };
+    };
+
+    auto a8 = [=, this] {
+    // { dg-warning "explicit by-copy capture" "" { target c++17_down } .-1 }
+      auto a = [=, this] {
+    // { dg-warning "explicit by-copy capture" "" { target c++17_down } .-1 }
+        auto a2 = [=, this] { x = n; };
+    // { dg-warning "explicit by-copy capture" "" { target c++17_down } .-1 }
+      };
+    };
+
+    auto a9 = [=, *this]() mutable {
+      auto a = [=, *this]() mutable {
+        auto a2 = [=, *this]() mutable { x = n; };
+      };
+    };
+
+    auto a10 = [&] {
+      auto a = [&] {
+        auto a2 = [&] { x = n; };
+      };
+    };
+
+    auto a11 = [&, this] {
+      auto a = [&, this] {
+        auto a2 = [&, this] { x = n; };
+      };
+    };
+
+    auto a12 = [&, *this]() mutable {
+      auto a = [&, *this]() mutable {
+        auto a2 = [&, *this]() mutable { x = n; };
+      };
+    };
+  }
+};