[clang] 5baea05 - [SEH] Fix capture of this in lambda functions

Olivier Goffart via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 11 00:13:20 PST 2021


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 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]])


        


More information about the cfe-commits mailing list