Skip to content

Commit 5baea05

Browse files
committed
[SEH] Fix capture of this in lambda functions
Commit 1b04bdc 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 lambda capture was not handled properly Differential Revision: https://reviews.llvm.org/D97687
1 parent aeaf705 commit 5baea05

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

clang/lib/CodeGen/CGException.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,8 +1879,24 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,
18791879
setAddrOfLocalVar(VD, Recovered);
18801880

18811881
if (isa<ImplicitParamDecl>(VD)) {
1882-
CXXThisValue = Builder.CreateLoad(Recovered, "this");
1883-
CXXABIThisValue = CXXThisValue;
1882+
CXXABIThisAlignment = ParentCGF.CXXABIThisAlignment;
1883+
CXXThisAlignment = ParentCGF.CXXThisAlignment;
1884+
CXXABIThisValue = Builder.CreateLoad(Recovered, "this");
1885+
if (ParentCGF.LambdaThisCaptureField) {
1886+
LambdaThisCaptureField = ParentCGF.LambdaThisCaptureField;
1887+
// We are in a lambda function where "this" is captured so the
1888+
// CXXThisValue need to be loaded from the lambda capture
1889+
LValue ThisFieldLValue =
1890+
EmitLValueForLambdaField(LambdaThisCaptureField);
1891+
if (!LambdaThisCaptureField->getType()->isPointerType()) {
1892+
CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer();
1893+
} else {
1894+
CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation())
1895+
.getScalarVal();
1896+
}
1897+
} else {
1898+
CXXThisValue = CXXABIThisValue;
1899+
}
18841900
}
18851901
}
18861902

@@ -1949,6 +1965,7 @@ void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF,
19491965
StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
19501966
OutlinedStmt->getBeginLoc(), OutlinedStmt->getBeginLoc());
19511967
CurSEHParent = ParentCGF.CurSEHParent;
1968+
CurCodeDecl = ParentCGF.CurCodeDecl;
19521969

19531970
CGM.SetInternalFunctionAttributes(GlobalDecl(), CurFn, FnInfo);
19541971
EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);

clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,25 @@ void test_lambda() {
123123
// CHECK: %[[l1_ref:[^ ]*]] = load i32*, i32** %[[l1_ref_ptr]]
124124
// CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ref]]
125125
// CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]], i32 %[[l2]])
126+
127+
struct U {
128+
void this_in_lambda();
129+
};
130+
131+
void U::this_in_lambda() {
132+
auto lambda = [=]() {
133+
__try {
134+
might_crash();
135+
} __except (basic_filter(0, this)) {
136+
}
137+
};
138+
lambda();
139+
}
140+
141+
// CHECK-LABEL: define internal i32 @"?filt$0@0@?R<lambda_1>@?0??this_in_lambda@U@@QEAAXXZ@"(i8* %exception_pointers, i8* %frame_pointer)
142+
// CHECK: %[[this_i8:[^ ]*]] = call i8* @llvm.localrecover(i8* bitcast (void (%class.anon.0*)* @"??R<lambda_1>@?0??this_in_lambda@U@@QEAAXXZ@QEBA@XZ" to i8*), i8* %[[fp:[^ ]*]], i32 0)
143+
// CHECK: %[[this_ptr:[^ ]*]] = bitcast i8* %[[this_i8]] to %class.anon.0**
144+
// CHECK: %[[this:[^ ]*]] = load %class.anon.0*, %class.anon.0** %[[this_ptr]], align 8
145+
// CHECK: %[[actual_this_ptr:[^ ]*]] = getelementptr inbounds %class.anon.0, %class.anon.0* %[[this]], i32 0, i32 0
146+
// CHECK: %[[actual_this:[^ ]*]] = load %struct.U*, %struct.U** %[[actual_this_ptr]], align 8
147+
// CHECK: call i32 (i32, ...) @basic_filter(i32 0, %struct.U* %[[actual_this]])

0 commit comments

Comments
 (0)