vitalybuka created this revision. Herald added a project: All. vitalybuka requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Lambda invoker sets this argument to Undef, making it inconsistent with noundef, notnull, and dereferencable attributes. This is especially confusing for Msan. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D132275 Files: clang/lib/CodeGen/CGClass.cpp clang/lib/CodeGen/CodeGenFunction.h clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp Index: clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp =================================================================== --- clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp +++ clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp @@ -3,9 +3,9 @@ // 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: call void @"??R<lambda_0>@?0??test@@YAXXZ@QEBA@UTrivial@@@Z"(ptr align 1 undef, -// 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 align 1 %this, struct Trivial { int x; Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -2219,7 +2219,8 @@ void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S); void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator, - CallArgList &CallArgs); + CallArgList &CallArgs, + llvm::CallBase **CallOrInvoke); void EmitLambdaBlockInvokeBody(); void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD); void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD); Index: clang/lib/CodeGen/CGClass.cpp =================================================================== --- clang/lib/CodeGen/CGClass.cpp +++ clang/lib/CodeGen/CGClass.cpp @@ -2894,8 +2894,8 @@ } void CodeGenFunction::EmitForwardingCallToLambda( - const CXXMethodDecl *callOperator, - CallArgList &callArgs) { + const CXXMethodDecl *callOperator, CallArgList &callArgs, + llvm::CallBase **callOrInvoke) { // Get the address of the call operator. const CGFunctionInfo &calleeFnInfo = CGM.getTypes().arrangeCXXMethodDeclaration(callOperator); @@ -2921,7 +2921,7 @@ // Now emit our call. auto callee = CGCallee::forDirect(calleePtr, GlobalDecl(callOperator)); - RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs); + RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs, callOrInvoke); // If necessary, copy the returned value into the slot. if (!resultType->isVoidType() && returnSlot.isNull()) { @@ -2960,7 +2960,7 @@ assert(!Lambda->isGenericLambda() && "generic lambda interconversion to block not implemented"); - EmitForwardingCallToLambda(CallOp, CallArgs); + EmitForwardingCallToLambda(CallOp, CallArgs, nullptr); } void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) { @@ -2990,7 +2990,16 @@ assert(CorrespondingCallOpSpecialization); CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization); } - EmitForwardingCallToLambda(CallOp, CallArgs); + llvm::CallBase *CallOrInvoke = nullptr; + EmitForwardingCallToLambda(CallOp, CallArgs, &CallOrInvoke); + if (CallOrInvoke) { + // ThisPtr is Undef, so we need to reset incompatible attributes. + const auto &ToRemove = + llvm::AttributeFuncs::getUBImplyingAttributes().addAttribute( + llvm::Attribute::NonNull); + CallOrInvoke->getCalledFunction()->removeParamAttrs(0, ToRemove); + CallOrInvoke->removeParamAttrs(0, ToRemove); + } } void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) {
Index: clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp =================================================================== --- clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp +++ clang/test/CodeGenCXX/lambda-to-function-pointer-conversion.cpp @@ -3,9 +3,9 @@ // 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: call void @"??R<lambda_0>@?0??test@@YAXXZ@QEBA@UTrivial@@@Z"(ptr align 1 undef, -// 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 align 1 %this, struct Trivial { int x; Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -2219,7 +2219,8 @@ void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S); void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator, - CallArgList &CallArgs); + CallArgList &CallArgs, + llvm::CallBase **CallOrInvoke); void EmitLambdaBlockInvokeBody(); void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD); void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD); Index: clang/lib/CodeGen/CGClass.cpp =================================================================== --- clang/lib/CodeGen/CGClass.cpp +++ clang/lib/CodeGen/CGClass.cpp @@ -2894,8 +2894,8 @@ } void CodeGenFunction::EmitForwardingCallToLambda( - const CXXMethodDecl *callOperator, - CallArgList &callArgs) { + const CXXMethodDecl *callOperator, CallArgList &callArgs, + llvm::CallBase **callOrInvoke) { // Get the address of the call operator. const CGFunctionInfo &calleeFnInfo = CGM.getTypes().arrangeCXXMethodDeclaration(callOperator); @@ -2921,7 +2921,7 @@ // Now emit our call. auto callee = CGCallee::forDirect(calleePtr, GlobalDecl(callOperator)); - RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs); + RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs, callOrInvoke); // If necessary, copy the returned value into the slot. if (!resultType->isVoidType() && returnSlot.isNull()) { @@ -2960,7 +2960,7 @@ assert(!Lambda->isGenericLambda() && "generic lambda interconversion to block not implemented"); - EmitForwardingCallToLambda(CallOp, CallArgs); + EmitForwardingCallToLambda(CallOp, CallArgs, nullptr); } void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) { @@ -2990,7 +2990,16 @@ assert(CorrespondingCallOpSpecialization); CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization); } - EmitForwardingCallToLambda(CallOp, CallArgs); + llvm::CallBase *CallOrInvoke = nullptr; + EmitForwardingCallToLambda(CallOp, CallArgs, &CallOrInvoke); + if (CallOrInvoke) { + // ThisPtr is Undef, so we need to reset incompatible attributes. + const auto &ToRemove = + llvm::AttributeFuncs::getUBImplyingAttributes().addAttribute( + llvm::Attribute::NonNull); + CallOrInvoke->getCalledFunction()->removeParamAttrs(0, ToRemove); + CallOrInvoke->removeParamAttrs(0, ToRemove); + } } void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits