[clang] b5a9adf - [clang] Create alloca to pass into static lambda

Vitaly Buka via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 23 13:53:31 PDT 2022


Author: Vitaly Buka
Date: 2022-08-23T13:53:17-07:00
New Revision: b5a9adf1f533c6403d780bb127bda4b53f7dc7ed

URL: https://github.com/llvm/llvm-project/commit/b5a9adf1f533c6403d780bb127bda4b53f7dc7ed
DIFF: https://github.com/llvm/llvm-project/commit/b5a9adf1f533c6403d780bb127bda4b53f7dc7ed.diff

LOG: [clang] Create alloca to pass into static lambda

"this" parameter of lambda if undef, notnull and differentiable.
So we need to pass something consistent.

Any alloca will work. It will be eliminated as unused later by optimizer.

Otherwise we generate code which Msan is expected to catch.

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D132275

Added: 
    

Modified: 
    clang/lib/CodeGen/CGClass.cpp
    clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 47dea725a051..703eff8ac54c 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2969,9 +2969,10 @@ void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {
   // Start building arguments for forwarding call
   CallArgList CallArgs;
 
-  QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda));
-  llvm::Value *ThisPtr = llvm::UndefValue::get(getTypes().ConvertType(ThisType));
-  CallArgs.add(RValue::get(ThisPtr), ThisType);
+  QualType LambdaType = getContext().getRecordType(Lambda);
+  QualType ThisType = getContext().getPointerType(LambdaType);
+  Address ThisPtr = CreateMemTemp(LambdaType, "unused.capture");
+  CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType);
 
   // Add the rest of the parameters.
   for (auto Param : MD->parameters())

diff  --git a/clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp b/clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp
index 87d21a3461d2..be986a4f6eda 100644
--- a/clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp
+++ b/clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp
@@ -2,10 +2,11 @@
 
 // This code used to cause an assertion failure in EmitDelegateCallArg.
 
-// CHECK: define internal void @"?__invoke@<lambda_0>@?0??test@@YAXXZ at CA@UTrivial@@@Z"(
-// CHECK: call void @"??R<lambda_0>@?0??test@@YAXXZ at QEBA@UTrivial@@@Z"(
+// CHECK-LABEL: define internal void @"?__invoke@<lambda_0>@?0??test@@YAXXZ at CA@UTrivial@@@Z"(
+// CHECK: %unused.capture = alloca %class.anon, align 1
+// CHECK: call void @"??R<lambda_0>@?0??test@@YAXXZ at QEBA@UTrivial@@@Z"(ptr noundef nonnull align 1 dereferenceable(1) %unused.capture,
 
-// CHECK: define internal void @"??R<lambda_0>@?0??test@@YAXXZ at QEBA@UTrivial@@@Z"(
+// CHECK: define internal void @"??R<lambda_0>@?0??test@@YAXXZ at QEBA@UTrivial@@@Z"(ptr noundef nonnull align 1 dereferenceable(1) %this,
 
 struct Trivial {
   int x;
@@ -16,3 +17,15 @@ void (*fnptr)(Trivial);
 void test() {
   fnptr = [](Trivial a){ (void)a; };
 }
+
+// CHECK-LABEL: define internal i32 @"?__invoke@<lambda_1>@?0??test2@@YAXXZ at CA@H at Z"(
+// CHECK: %unused.capture = alloca %class.anon.0, align 1
+// CHECK: call void @"??R<lambda_1>@?0??test2@@YAXXZ at QEBA@H at Z"(ptr noundef nonnull align 1 dereferenceable(1) %unused.capture,
+
+// CHECK: define internal void @"??R<lambda_1>@?0??test2@@YAXXZ at QEBA@H at Z"(ptr noundef nonnull align 1 dereferenceable(1) %this,
+
+Trivial (*fnptr2)(int);
+
+void test2() {
+  fnptr2 = [](int) -> Trivial { return {}; };
+}


        


More information about the cfe-commits mailing list