Author: Olivier Goffart Date: 2021-03-11T09:12:42+01:00 New Revision: 5baea0560160a693b19022c5d0ba637b6b46b2d8
URL: https://github.com/llvm/llvm-project/commit/5baea0560160a693b19022c5d0ba637b6b46b2d8 DIFF: https://github.com/llvm/llvm-project/commit/5baea0560160a693b19022c5d0ba637b6b46b2d8.diff LOG: [SEH] Fix capture of this in lambda functions Commit 1b04bdc2f3ffaa7a0e1e3dbdc3a0cd08f0b9a4ce 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 Added: Modified: clang/lib/CodeGen/CGException.cpp clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 97e2a3a4b69a..5ac037cd9db9 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -1879,8 +1879,24 @@ void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF, 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; + } } } @@ -1949,6 +1965,7 @@ void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF, 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); diff --git a/clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp b/clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp index f6cca8eda9d9..6b5c27097cbd 100644 --- a/clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp +++ b/clang/test/CodeGenCXX/exceptions-seh-filter-captures.cpp @@ -123,3 +123,25 @@ void test_lambda() { // 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@0@?R<lambda_1>@?0??this_in_lambda@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@U@@QEAAXXZ@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]]) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits