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@CA@UTrivial@@@Z"( -// CHECK: call void @"??R<lambda_0>@?0??test@@YAXXZ@QEBA@UTrivial@@@Z"( +// CHECK-LABEL: define internal void @"?__invoke@<lambda_0>@?0??test@@YAXXZ@CA@UTrivial@@@Z"( +// CHECK: %unused.capture = alloca %class.anon, align 1 +// CHECK: call void @"??R<lambda_0>@?0??test@@YAXXZ@QEBA@UTrivial@@@Z"(ptr noundef nonnull align 1 dereferenceable(1) %unused.capture, -// CHECK: define internal void @"??R<lambda_0>@?0??test@@YAXXZ@QEBA@UTrivial@@@Z"( +// CHECK: define internal void @"??R<lambda_0>@?0??test@@YAXXZ@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@CA@H@Z"( +// CHECK: %unused.capture = alloca %class.anon.0, align 1 +// CHECK: call void @"??R<lambda_1>@?0??test2@@YAXXZ@QEBA@H@Z"(ptr noundef nonnull align 1 dereferenceable(1) %unused.capture, + +// CHECK: define internal void @"??R<lambda_1>@?0??test2@@YAXXZ@QEBA@H@Z"(ptr noundef nonnull align 1 dereferenceable(1) %this, + +Trivial (*fnptr2)(int); + +void test2() { + fnptr2 = [](int) -> Trivial { return {}; }; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits