This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C++ PATCH to implement C++20 P0806R2, Deprecate implicit capture of this via [=]


On Mon, Aug 13, 2018 at 06:27:53PM +1200, Jason Merrill wrote:
> On Sun, Aug 12, 2018 at 3:53 PM, Marek Polacek <polacek@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  <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 [=].

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]