[PATCH] D97687: [SEH] Fix capture of this in lambda functions
Olivier Goffart via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 1 07:25:33 PST 2021
ogoffart created this revision.
ogoffart added a reviewer: rnk.
ogoffart requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Commit 1b04bdc2f3ffaa7a0e1e3dbdc3a0cd08f0b9a4ce <https://reviews.llvm.org/rG1b04bdc2f3ffaa7a0e1e3dbdc3a0cd08f0b9a4ce> added support for
capturing the 'this' pointer in a SEH context (__finally or __except),
But the case in which the 'this' pointer is part of a lamdda capture
was not handled properly
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D97687
Files:
clang/lib/CodeGen/CGException.cpp
clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
Index: clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
===================================================================
--- clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
+++ clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp
@@ -123,3 +123,25 @@
// CHECK: %[[l1_ref:[^ ]*]] = load i32*, i32** %[[l1_ref_ptr]]
// CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ref]]
// CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]], i32 %[[l2]])
+
+struct U {
+ void this_in_lambda();
+};
+
+void U::this_in_lambda() {
+ auto lambda = [=]() {
+ __try {
+ might_crash();
+ } __except (basic_filter(0, this)) {
+ }
+ };
+ lambda();
+}
+
+// CHECK-LABEL: define internal i32 @"?filt$0 at 0@?R<lambda_1>@?0??this_in_lambda at U@@QEAAXXZ@"(i8* %exception_pointers, i8* %frame_pointer)
+// CHECK: %[[this_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon.0*)* @"??R<lambda_1>@?0??this_in_lambda at U@@QEAAXXZ at QEBA@XZ" to i8*), i8* %[[fp:[^ ]*]], i32 0)
+// CHECK: %[[this_ptr:[^ ]*]] = bitcast i8* %[[this_i8]] to %class.anon.0**
+// CHECK: %[[this:[^ ]*]] = load %class.anon.0*, %class.anon.0** %[[this_ptr]], align 8
+// CHECK: %[[actual_this_ptr:[^ ]*]] = getelementptr inbounds %class.anon.0, %class.anon.0* %[[this]], i32 0, i32 0
+// CHECK: %[[actual_this:[^ ]*]] = load %struct.U*, %struct.U** %[[actual_this_ptr]], align 8
+// CHECK: call i32 (i32, ...) @basic_filter(i32 0, %struct.U* %[[actual_this]])
Index: clang/lib/CodeGen/CGException.cpp
===================================================================
--- clang/lib/CodeGen/CGException.cpp
+++ clang/lib/CodeGen/CGException.cpp
@@ -1888,8 +1888,24 @@
setAddrOfLocalVar(VD, Recovered);
if (isa<ImplicitParamDecl>(VD)) {
- CXXThisValue = Builder.CreateLoad(Recovered, "this");
- CXXABIThisValue = CXXThisValue;
+ CXXABIThisAlignment = ParentCGF.CXXABIThisAlignment;
+ CXXThisAlignment = ParentCGF.CXXThisAlignment;
+ CXXABIThisValue = Builder.CreateLoad(Recovered, "this");
+ if (ParentCGF.LambdaThisCaptureField) {
+ LambdaThisCaptureField = ParentCGF.LambdaThisCaptureField;
+ // We are in a lambda function where "this" is captured so the
+ // CXXThisValue need to be loaded from the lambda capture
+ LValue ThisFieldLValue =
+ EmitLValueForLambdaField(LambdaThisCaptureField);
+ if (!LambdaThisCaptureField->getType()->isPointerType()) {
+ CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer();
+ } else {
+ CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation())
+ .getScalarVal();
+ }
+ } else {
+ CXXThisValue = CXXABIThisValue;
+ }
}
}
@@ -1958,6 +1974,7 @@
StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
OutlinedStmt->getBeginLoc(), OutlinedStmt->getBeginLoc());
CurSEHParent = ParentCGF.CurSEHParent;
+ CurCodeDecl = ParentCGF.CurCodeDecl;
CGM.SetInternalFunctionAttributes(GlobalDecl(), CurFn, FnInfo);
EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D97687.327108.patch
Type: text/x-patch
Size: 3111 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210301/4dfdc89b/attachment.bin>
More information about the cfe-commits
mailing list