r336480 - P0806R2 Implicit capture of this with a capture-default of [=] is

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 6 22:58:49 PDT 2018


Author: rsmith
Date: Fri Jul  6 22:58:48 2018
New Revision: 336480

URL: http://llvm.org/viewvc/llvm-project?rev=336480&view=rev
Log:
P0806R2 Implicit capture of this with a capture-default of [=] is
deprecated.

Add a -Wdeprecated warning for this in C++2a onwards. (In C++17 and
before, there isn't a reasonable alternative because [=,this] is
ill-formed.)

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaLambda.cpp
    cfe/trunk/test/SemaCXX/cxx2a-lambda-equals-this.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=336480&r1=336479&r2=336480&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Jul  6 22:58:48 2018
@@ -120,6 +120,7 @@ def DeprecatedDynamicExceptionSpec
 def DeprecatedImplementations :DiagGroup<"deprecated-implementations">;
 def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">;
 def DeprecatedRegister : DiagGroup<"deprecated-register">;
+def DeprecatedThisCapture : DiagGroup<"deprecated-this-capture">;
 def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
                                       [CXX11CompatDeprecatedWritableStr]>;
 // FIXME: Why is DeprecatedImplementations not in this group?
@@ -128,6 +129,7 @@ def Deprecated : DiagGroup<"deprecated",
                                           DeprecatedDynamicExceptionSpec,
                                           DeprecatedIncrementBool,
                                           DeprecatedRegister,
+                                          DeprecatedThisCapture,
                                           DeprecatedWritableStr]>,
                  DiagCategory<"Deprecations">;
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=336480&r1=336479&r2=336480&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jul  6 22:58:48 2018
@@ -6545,6 +6545,11 @@ let CategoryName = "Lambda Issue" in {
   def ext_equals_this_lambda_capture_cxx2a : ExtWarn<
     "explicit capture of 'this' with a capture default of '=' "
     "is a C++2a extension">, InGroup<CXX2a>;
+  def warn_deprecated_this_capture : Warning<
+    "implicit capture of 'this' with a capture default of '=' is deprecated">,
+    InGroup<DeprecatedThisCapture>, DefaultIgnore;
+  def note_deprecated_this_capture : Note<
+    "add an explicit capture of 'this' to capture '*this' by reference">;
 }
 
 def err_return_in_captured_stmt : Error<

Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=336480&r1=336479&r2=336480&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Fri Jul  6 22:58:48 2018
@@ -1548,6 +1548,17 @@ ExprResult Sema::BuildLambdaExpr(SourceL
 
       // Handle 'this' capture.
       if (From.isThisCapture()) {
+        // Capturing 'this' implicitly with a default of '[=]' is deprecated,
+        // because it results in a reference capture. Don't warn prior to
+        // C++2a; there's nothing that can be done about it before then.
+        if (getLangOpts().CPlusPlus2a && IsImplicit &&
+            CaptureDefault == LCD_ByCopy) {
+          Diag(From.getLocation(), diag::warn_deprecated_this_capture);
+          Diag(CaptureDefaultLoc, diag::note_deprecated_this_capture)
+              << FixItHint::CreateInsertion(
+                     getLocForEndOfToken(CaptureDefaultLoc), ", this");
+        }
+
         Captures.push_back(
             LambdaCapture(From.getLocation(), IsImplicit,
                           From.isCopyCapture() ? LCK_StarThis : LCK_This));

Modified: cfe/trunk/test/SemaCXX/cxx2a-lambda-equals-this.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx2a-lambda-equals-this.cpp?rev=336480&r1=336479&r2=336480&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx2a-lambda-equals-this.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx2a-lambda-equals-this.cpp Fri Jul  6 22:58:48 2018
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++2a -verify %s -Wdeprecated
 
 // This test does two things.
 // Deleting the copy constructor ensures that an [=, this] capture doesn't copy the object.
@@ -13,3 +12,12 @@ class A {
     L();
   }
 };
+
+struct B {
+  int i;
+  void f() {
+    (void) [=] { // expected-note {{add an explicit capture of 'this'}}
+      return i; // expected-warning {{implicit capture of 'this' with a capture default of '=' is deprecated}}
+    };
+  }
+};




More information about the cfe-commits mailing list