On Mon, Aug 13, 2018 at 06:27:53PM +1200, Jason Merrill wrote:
> On Sun, Aug 12, 2018 at 3:53 PM, Marek Polacek <pola...@redhat.com> wrote:
> > -      var = add_capture (lambda,
> > -                            id,
> > -                            initializer,
> > -                            /*by_reference_p=*/
> > -                           (this_capture_p
> > -                            || (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda)
> > -                                == CPLD_REFERENCE)),
> > -                           /*explicit_init_p=*/false);
> > +      var = add_capture (lambda, id, initializer,
> > +                        /*by_reference_p=*/
> > +                        (this_capture_p
> > +                         || (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda)
> > +                             == CPLD_REFERENCE)),
> > +                        /*explicit_init_p=*/false);
> 
> This reformatting seems unnecessary, and I prefer to avoid unnecessary
> reformatting to avoid noise in 'git blame'. The rest of the patch is
> OK.

Thanks, this is what I committed.

2018-08-13  Marek Polacek  <pola...@redhat.com>

        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.

--- gcc/cp/lambda.c
+++ gcc/cp/lambda.c
@@ -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;
--- gcc/testsuite/g++.dg/cpp2a/lambda-this1.C
+++ gcc/testsuite/g++.dg/cpp2a/lambda-this1.C
@@ -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; };
+      };
+    };
+  }
+};
--- gcc/testsuite/g++.dg/cpp2a/lambda-this2.C
+++ gcc/testsuite/g++.dg/cpp2a/lambda-this2.C
@@ -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; };
+      };
+    };
+  }
+};
--- gcc/testsuite/g++.dg/cpp2a/lambda-this3.C
+++ gcc/testsuite/g++.dg/cpp2a/lambda-this3.C
@@ -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; };
+      };
+    };
+  }
+};

Reply via email to