[clang] 0eb06cb - [Sema] Stop stripping CV quals from *this captures in lambdas

Roy Jacobson via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 29 13:11:58 PDT 2023


Author: Roy Jacobson
Date: 2023-03-29T23:11:51+03:00
New Revision: 0eb06cb3aa2700508c20da28f22ff91e7b82a436

URL: https://github.com/llvm/llvm-project/commit/0eb06cb3aa2700508c20da28f22ff91e7b82a436
DIFF: https://github.com/llvm/llvm-project/commit/0eb06cb3aa2700508c20da28f22ff91e7b82a436.diff

LOG: [Sema] Stop stripping CV quals from *this captures in lambdas

It appears we've been incorrectly stripping CV qualifiers when capturing `this` by value inside lambdas.
This patch simply removes the CV stripping code as discussed.

Closes https://github.com/llvm/llvm-project/issues/50866

Reviewed By: #clang-language-wg, cor3ntin, aaron.ballman

Differential Revision: https://reviews.llvm.org/D146168

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaExprCXX.cpp
    clang/test/SemaCXX/cxx1z-lambda-star-this.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 271e01b8a47d5..44ffca26f26a2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -277,6 +277,9 @@ Bug Fixes to C++ Support
 - No longer issue a pre-C++2b compatibility warning in ``-pedantic`` mode
   regading overloaded `operator[]` with more than one parmeter or for static
   lambdas. (`#61582 <https://github.com/llvm/llvm-project/issues/61582>`_)
+- Stop stripping CV qualifiers from the type of ``this`` when capturing it by value in
+  a lambda.
+  (`#50866 <https://github.com/llvm/llvm-project/issues/50866>`_)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index d5aeb38245ad7..5c3a21583f856 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1135,7 +1135,6 @@ static QualType adjustCVQualifiersForCXXThisWithinLambda(
     auto C = CurLSI->getCXXThisCapture();
 
     if (C.isCopyCapture()) {
-      ClassType.removeLocalCVRQualifiers(Qualifiers::CVRMask);
       if (!CurLSI->Mutable)
         ClassType.addConst();
       return ASTCtx.getPointerType(ClassType);
@@ -1175,7 +1174,6 @@ static QualType adjustCVQualifiersForCXXThisWithinLambda(
     while (Closure &&
            IsThisCaptured(Closure, IsByCopyCapture, IsConstCapture)) {
       if (IsByCopyCapture) {
-        ClassType.removeLocalCVRQualifiers(Qualifiers::CVRMask);
         if (IsConstCapture)
           ClassType.addConst();
         return ASTCtx.getPointerType(ClassType);
@@ -1362,15 +1360,7 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit,
 
     // The type of the corresponding data member (not a 'this' pointer if 'by
     // copy').
-    QualType CaptureType = ThisTy;
-    if (ByCopy) {
-      // If we are capturing the object referred to by '*this' by copy, ignore
-      // any cv qualifiers inherited from the type of the member function for
-      // the type of the closure-type's corresponding data member and any use
-      // of 'this'.
-      CaptureType = ThisTy->getPointeeType();
-      CaptureType.removeLocalCVRQualifiers(Qualifiers::CVRMask);
-    }
+    QualType CaptureType = ByCopy ? ThisTy->getPointeeType() : ThisTy;
 
     bool isNested = NumCapturingClosures > 1;
     CSI->addThisCapture(isNested, Loc, CaptureType, ByCopy);

diff  --git a/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp b/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
index 5a471fd6b6940..95bc32b603ddf 100644
--- a/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
+++ b/clang/test/SemaCXX/cxx1z-lambda-star-this.cpp
@@ -88,13 +88,11 @@ struct X {
   void foo() const { //expected-note{{const}}
 
     auto L = [*this]() mutable {
-      static_assert(is_same<decltype(this), X *>);
-      ++d;
+      static_assert(is_same<decltype(this), const X *>);
       auto M = [this] {
-        static_assert(is_same<decltype(this), X *>);
-        ++d;
+        static_assert(is_same<decltype(this), const X *>);
         auto N = [] {
-          static_assert(is_same<decltype(this), X *>);
+          static_assert(is_same<decltype(this), const X *>);
         };
       };
     };
@@ -108,9 +106,9 @@ struct X {
         };
       };
       auto M2 = [*this]() mutable {
-        static_assert(is_same<decltype(this), X *>);
+        static_assert(is_same<decltype(this), const X *>);
         auto N = [] {
-          static_assert(is_same<decltype(this), X *>);
+          static_assert(is_same<decltype(this), const X *>);
         };
       };
     };
@@ -126,9 +124,9 @@ struct X {
       };
 
       auto M2 = [*this](auto a) mutable {
-        static_assert(is_same<decltype(this), X *>);
+        static_assert(is_same<decltype(this), const X *>);
         auto N = [](auto b) {
-          static_assert(is_same<decltype(this), X *>);
+          static_assert(is_same<decltype(this), const X *>);
         };
         return N;
       };
@@ -143,13 +141,11 @@ struct X {
       ++d; //expected-error{{cannot assign}}
     };
     auto GL = [*this](auto a) mutable {
-      static_assert(is_same<decltype(this), X *>);
-      ++d;
+      static_assert(is_same<decltype(this), const X *>);
       auto M = [this](auto b) {
-        static_assert(is_same<decltype(this), X *>);
-        ++d;
+        static_assert(is_same<decltype(this), const X *>);
         auto N = [](auto c) {
-          static_assert(is_same<decltype(this), X *>);
+          static_assert(is_same<decltype(this), const X *>);
         };
         N(3.14);
       };
@@ -161,21 +157,21 @@ struct X {
     auto L = [this]() {
       static_assert(is_same<decltype(this), const volatile X *>);
       auto M = [*this]() mutable {
-        static_assert(is_same<decltype(this), X *>);
+        static_assert(is_same<decltype(this), const volatile X *>);
         auto N = [this] {
-          static_assert(is_same<decltype(this), X *>);
+          static_assert(is_same<decltype(this), const volatile X *>);
           auto M = [] {
-            static_assert(is_same<decltype(this), X *>);
+            static_assert(is_same<decltype(this), const volatile X *>);
           };
         };
         auto N2 = [*this] {
-          static_assert(is_same<decltype(this), const X *>);
+          static_assert(is_same<decltype(this), const volatile X *>);
         };
       };
       auto M2 = [*this]() {
-        static_assert(is_same<decltype(this), const X *>);
+        static_assert(is_same<decltype(this), const volatile X *>);
         auto N = [this] {
-          static_assert(is_same<decltype(this), const X *>);
+          static_assert(is_same<decltype(this), const volatile X *>);
         };
       };
     };
@@ -190,14 +186,13 @@ struct X {
     auto L = [*this]() mutable {
       auto M = [=](auto a) {
         auto N = [this] {
-          ++d;
-          static_assert(is_same<decltype(this), X *>);
+          static_assert(is_same<decltype(this), const X *>);
           auto O = [*this] {
             static_assert(is_same<decltype(this), const X *>);
           };
         };
         N();
-        static_assert(is_same<decltype(this), X *>);
+        static_assert(is_same<decltype(this), const X *>);
       };
       return M;
     };
@@ -308,3 +303,22 @@ void A::f() {
     z(id,3);
 }
 } // namespace PR45881
+
+
+namespace GH50866 {
+struct S;
+
+void f(S *) = delete; // expected-note {{would lose const qualifier}}
+void f(const S *) = delete; // expected-note {{candidate function has been explicitly deleted}}
+
+struct S {
+  void g() const {
+    [*this]() mutable { f(this); }(); // expected-error {{call to deleted function}}
+  }
+};
+
+void g() {
+  S s{};
+  s.g();
+}
+}


        


More information about the cfe-commits mailing list