[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