[clang] 8ed7aa5 - Revert "Try to implement lambdas with inalloca parameters by forwarding without use of inallocas."
Amy Huang via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 22 11:42:46 PDT 2023
Author: Amy Huang
Date: 2023-06-22T11:42:33-07:00
New Revision: 8ed7aa59f489715d39d32e72a787b8e75cfda151
URL: https://github.com/llvm/llvm-project/commit/8ed7aa59f489715d39d32e72a787b8e75cfda151
DIFF: https://github.com/llvm/llvm-project/commit/8ed7aa59f489715d39d32e72a787b8e75cfda151.diff
LOG: Revert "Try to implement lambdas with inalloca parameters by forwarding without use of inallocas."
Causes a clang crash (see crbug.com/1457256).
This reverts commit 015049338d7e8e0e81f2ad2f94e5a43e2e3f5220.
Added:
Modified:
clang/include/clang/CodeGen/CGFunctionInfo.h
clang/lib/CodeGen/CGCall.cpp
clang/lib/CodeGen/CGCall.h
clang/lib/CodeGen/CGClass.cpp
clang/lib/CodeGen/CGDeclCXX.cpp
clang/lib/CodeGen/CodeGenABITypes.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/lib/CodeGen/CodeGenTypes.h
clang/lib/CodeGen/Targets/X86.cpp
clang/test/CodeGenCXX/inalloca-lambda.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/CodeGen/CGFunctionInfo.h b/clang/include/clang/CodeGen/CGFunctionInfo.h
index b8971d5793f36..39c7a578c8c4e 100644
--- a/clang/include/clang/CodeGen/CGFunctionInfo.h
+++ b/clang/include/clang/CodeGen/CGFunctionInfo.h
@@ -567,10 +567,6 @@ class CGFunctionInfo final
/// Whether this is a chain call.
unsigned ChainCall : 1;
- /// Whether this function is called by forwarding arguments.
- /// This doesn't support inalloca or varargs.
- unsigned DelegateCall : 1;
-
/// Whether this function is a CMSE nonsecure call
unsigned CmseNSCall : 1;
@@ -620,11 +616,14 @@ class CGFunctionInfo final
CGFunctionInfo() : Required(RequiredArgs::All) {}
public:
- static CGFunctionInfo *
- create(unsigned llvmCC, bool instanceMethod, bool chainCall,
- bool delegateCall, const FunctionType::ExtInfo &extInfo,
- ArrayRef<ExtParameterInfo> paramInfos, CanQualType resultType,
- ArrayRef<CanQualType> argTypes, RequiredArgs required);
+ static CGFunctionInfo *create(unsigned llvmCC,
+ bool instanceMethod,
+ bool chainCall,
+ const FunctionType::ExtInfo &extInfo,
+ ArrayRef<ExtParameterInfo> paramInfos,
+ CanQualType resultType,
+ ArrayRef<CanQualType> argTypes,
+ RequiredArgs required);
void operator delete(void *p) { ::operator delete(p); }
// Friending class TrailingObjects is apparently not good enough for MSVC,
@@ -664,8 +663,6 @@ class CGFunctionInfo final
bool isChainCall() const { return ChainCall; }
- bool isDelegateCall() const { return DelegateCall; }
-
bool isCmseNSCall() const { return CmseNSCall; }
bool isNoReturn() const { return NoReturn; }
@@ -752,7 +749,6 @@ class CGFunctionInfo final
ID.AddInteger(getASTCallingConvention());
ID.AddBoolean(InstanceMethod);
ID.AddBoolean(ChainCall);
- ID.AddBoolean(DelegateCall);
ID.AddBoolean(NoReturn);
ID.AddBoolean(ReturnsRetained);
ID.AddBoolean(NoCallerSavedRegs);
@@ -770,16 +766,17 @@ class CGFunctionInfo final
for (const auto &I : arguments())
I.type.Profile(ID);
}
- static void Profile(llvm::FoldingSetNodeID &ID, bool InstanceMethod,
- bool ChainCall, bool IsDelegateCall,
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ bool InstanceMethod,
+ bool ChainCall,
const FunctionType::ExtInfo &info,
ArrayRef<ExtParameterInfo> paramInfos,
- RequiredArgs required, CanQualType resultType,
+ RequiredArgs required,
+ CanQualType resultType,
ArrayRef<CanQualType> argTypes) {
ID.AddInteger(info.getCC());
ID.AddBoolean(InstanceMethod);
ID.AddBoolean(ChainCall);
- ID.AddBoolean(IsDelegateCall);
ID.AddBoolean(info.getNoReturn());
ID.AddBoolean(info.getProducesResult());
ID.AddBoolean(info.getNoCallerSavedRegs());
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index a9af9916b8c70..61029c9226d7b 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -111,7 +111,8 @@ CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP) {
// When translating an unprototyped function type, always use a
// variadic type.
return arrangeLLVMFunctionInfo(FTNP->getReturnType().getUnqualifiedType(),
- FnInfoOpts::None, std::nullopt,
+ /*instanceMethod=*/false,
+ /*chainCall=*/false, std::nullopt,
FTNP->getExtInfo(), {}, RequiredArgs(0));
}
@@ -187,10 +188,10 @@ arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod,
appendParameterTypes(CGT, prefix, paramInfos, FTP);
CanQualType resultType = FTP->getReturnType().getUnqualifiedType();
- FnInfoOpts opts =
- instanceMethod ? FnInfoOpts::IsInstanceMethod : FnInfoOpts::None;
- return CGT.arrangeLLVMFunctionInfo(resultType, opts, prefix,
- FTP->getExtInfo(), paramInfos, Required);
+ return CGT.arrangeLLVMFunctionInfo(resultType, instanceMethod,
+ /*chainCall=*/false, prefix,
+ FTP->getExtInfo(), paramInfos,
+ Required);
}
/// Arrange the argument and result information for a value of the
@@ -269,7 +270,7 @@ CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD,
argTypes.push_back(DeriveThisType(RD, MD));
return ::arrangeLLVMFunctionInfo(
- *this, /*instanceMethod=*/true, argTypes,
+ *this, true, argTypes,
FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
}
@@ -361,8 +362,9 @@ CodeGenTypes::arrangeCXXStructorDeclaration(GlobalDecl GD) {
: TheCXXABI.hasMostDerivedReturn(GD)
? CGM.getContext().VoidPtrTy
: Context.VoidTy;
- return arrangeLLVMFunctionInfo(resultType, FnInfoOpts::IsInstanceMethod,
- argTypes, extInfo, paramInfos, required);
+ return arrangeLLVMFunctionInfo(resultType, /*instanceMethod=*/true,
+ /*chainCall=*/false, argTypes, extInfo,
+ paramInfos, required);
}
static SmallVector<CanQualType, 16>
@@ -436,9 +438,9 @@ CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args,
addExtParameterInfosForCall(ParamInfos, FPT.getTypePtr(), TotalPrefixArgs,
ArgTypes.size());
}
-
- return arrangeLLVMFunctionInfo(ResultType, FnInfoOpts::IsInstanceMethod,
- ArgTypes, Info, ParamInfos, Required);
+ return arrangeLLVMFunctionInfo(ResultType, /*instanceMethod=*/true,
+ /*chainCall=*/false, ArgTypes, Info,
+ ParamInfos, Required);
}
/// Arrange the argument and result information for the declaration or
@@ -457,9 +459,10 @@ CodeGenTypes::arrangeFunctionDeclaration(const FunctionDecl *FD) {
// When declaring a function without a prototype, always use a
// non-variadic type.
if (CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>()) {
- return arrangeLLVMFunctionInfo(noProto->getReturnType(), FnInfoOpts::None,
- std::nullopt, noProto->getExtInfo(), {},
- RequiredArgs::All);
+ return arrangeLLVMFunctionInfo(
+ noProto->getReturnType(), /*instanceMethod=*/false,
+ /*chainCall=*/false, std::nullopt, noProto->getExtInfo(), {},
+ RequiredArgs::All);
}
return arrangeFreeFunctionType(FTy.castAs<FunctionProtoType>());
@@ -508,9 +511,9 @@ CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
RequiredArgs required =
(MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All);
- return arrangeLLVMFunctionInfo(GetReturnType(MD->getReturnType()),
- FnInfoOpts::None, argTys, einfo, extParamInfos,
- required);
+ return arrangeLLVMFunctionInfo(
+ GetReturnType(MD->getReturnType()), /*instanceMethod=*/false,
+ /*chainCall=*/false, argTys, einfo, extParamInfos, required);
}
const CGFunctionInfo &
@@ -519,8 +522,9 @@ CodeGenTypes::arrangeUnprototypedObjCMessageSend(QualType returnType,
auto argTypes = getArgTypesForCall(Context, args);
FunctionType::ExtInfo einfo;
- return arrangeLLVMFunctionInfo(GetReturnType(returnType), FnInfoOpts::None,
- argTypes, einfo, {}, RequiredArgs::All);
+ return arrangeLLVMFunctionInfo(
+ GetReturnType(returnType), /*instanceMethod=*/false,
+ /*chainCall=*/false, argTypes, einfo, {}, RequiredArgs::All);
}
const CGFunctionInfo &
@@ -545,7 +549,8 @@ CodeGenTypes::arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD) {
assert(MD->isVirtual() && "only methods have thunks");
CanQual<FunctionProtoType> FTP = GetFormalType(MD);
CanQualType ArgTys[] = {DeriveThisType(MD->getParent(), MD)};
- return arrangeLLVMFunctionInfo(Context.VoidTy, FnInfoOpts::None, ArgTys,
+ return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/false,
+ /*chainCall=*/false, ArgTys,
FTP->getExtInfo(), {}, RequiredArgs(1));
}
@@ -564,8 +569,9 @@ CodeGenTypes::arrangeMSCtorClosure(const CXXConstructorDecl *CD,
ArgTys.push_back(Context.IntTy);
CallingConv CC = Context.getDefaultCallingConvention(
/*IsVariadic=*/false, /*IsCXXMethod=*/true);
- return arrangeLLVMFunctionInfo(Context.VoidTy, FnInfoOpts::IsInstanceMethod,
- ArgTys, FunctionType::ExtInfo(CC), {},
+ return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/true,
+ /*chainCall=*/false, ArgTys,
+ FunctionType::ExtInfo(CC), {},
RequiredArgs::All);
}
@@ -609,10 +615,10 @@ arrangeFreeFunctionLikeCall(CodeGenTypes &CGT,
SmallVector<CanQualType, 16> argTypes;
for (const auto &arg : args)
argTypes.push_back(CGT.getContext().getCanonicalParamType(arg.Ty));
- FnInfoOpts opts = chainCall ? FnInfoOpts::IsChainCall : FnInfoOpts::None;
return CGT.arrangeLLVMFunctionInfo(GetReturnType(fnType->getReturnType()),
- opts, argTypes, fnType->getExtInfo(),
- paramInfos, required);
+ /*instanceMethod=*/false, chainCall,
+ argTypes, fnType->getExtInfo(), paramInfos,
+ required);
}
/// Figure out the rules for calling a function with the given formal
@@ -643,8 +649,8 @@ CodeGenTypes::arrangeBlockFunctionDeclaration(const FunctionProtoType *proto,
auto argTypes = getArgTypesForDeclaration(Context, params);
return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
- FnInfoOpts::None, argTypes,
- proto->getExtInfo(), paramInfos,
+ /*instanceMethod*/ false, /*chainCall*/ false,
+ argTypes, proto->getExtInfo(), paramInfos,
RequiredArgs::forPrototypePlus(proto, 1));
}
@@ -655,9 +661,10 @@ CodeGenTypes::arrangeBuiltinFunctionCall(QualType resultType,
SmallVector<CanQualType, 16> argTypes;
for (const auto &Arg : args)
argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
- return arrangeLLVMFunctionInfo(GetReturnType(resultType), FnInfoOpts::None,
- argTypes, FunctionType::ExtInfo(),
- /*paramInfos=*/{}, RequiredArgs::All);
+ return arrangeLLVMFunctionInfo(
+ GetReturnType(resultType), /*instanceMethod=*/false,
+ /*chainCall=*/false, argTypes, FunctionType::ExtInfo(),
+ /*paramInfos=*/ {}, RequiredArgs::All);
}
const CGFunctionInfo &
@@ -665,17 +672,17 @@ CodeGenTypes::arrangeBuiltinFunctionDeclaration(QualType resultType,
const FunctionArgList &args) {
auto argTypes = getArgTypesForDeclaration(Context, args);
- return arrangeLLVMFunctionInfo(GetReturnType(resultType), FnInfoOpts::None,
- argTypes, FunctionType::ExtInfo(), {},
- RequiredArgs::All);
+ return arrangeLLVMFunctionInfo(
+ GetReturnType(resultType), /*instanceMethod=*/false, /*chainCall=*/false,
+ argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All);
}
const CGFunctionInfo &
CodeGenTypes::arrangeBuiltinFunctionDeclaration(CanQualType resultType,
ArrayRef<CanQualType> argTypes) {
- return arrangeLLVMFunctionInfo(resultType, FnInfoOpts::None, argTypes,
- FunctionType::ExtInfo(), {},
- RequiredArgs::All);
+ return arrangeLLVMFunctionInfo(
+ resultType, /*instanceMethod=*/false, /*chainCall=*/false,
+ argTypes, FunctionType::ExtInfo(), {}, RequiredArgs::All);
}
/// Arrange a call to a C++ method, passing the given arguments.
@@ -698,15 +705,15 @@ CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,
auto argTypes = getArgTypesForCall(Context, args);
FunctionType::ExtInfo info = proto->getExtInfo();
- return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
- FnInfoOpts::IsInstanceMethod, argTypes, info,
- paramInfos, required);
+ return arrangeLLVMFunctionInfo(
+ GetReturnType(proto->getReturnType()), /*instanceMethod=*/true,
+ /*chainCall=*/false, argTypes, info, paramInfos, required);
}
const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() {
- return arrangeLLVMFunctionInfo(getContext().VoidTy, FnInfoOpts::None,
- std::nullopt, FunctionType::ExtInfo(), {},
- RequiredArgs::All);
+ return arrangeLLVMFunctionInfo(
+ getContext().VoidTy, /*instanceMethod=*/false, /*chainCall=*/false,
+ std::nullopt, FunctionType::ExtInfo(), {}, RequiredArgs::All);
}
const CGFunctionInfo &
@@ -726,15 +733,12 @@ CodeGenTypes::arrangeCall(const CGFunctionInfo &signature,
auto argTypes = getArgTypesForCall(Context, args);
assert(signature.getRequiredArgs().allowsOptionalArgs());
- FnInfoOpts opts = FnInfoOpts::None;
- if (signature.isInstanceMethod())
- opts |= FnInfoOpts::IsInstanceMethod;
- if (signature.isChainCall())
- opts |= FnInfoOpts::IsChainCall;
- if (signature.isDelegateCall())
- opts |= FnInfoOpts::IsDelegateCall;
- return arrangeLLVMFunctionInfo(signature.getReturnType(), opts, argTypes,
- signature.getExtInfo(), paramInfos,
+ return arrangeLLVMFunctionInfo(signature.getReturnType(),
+ signature.isInstanceMethod(),
+ signature.isChainCall(),
+ argTypes,
+ signature.getExtInfo(),
+ paramInfos,
signature.getRequiredArgs());
}
@@ -747,24 +751,21 @@ void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
/// Arrange the argument and result information for an abstract value
/// of a given function type. This is the method which all of the
/// above functions ultimately defer to.
-const CGFunctionInfo &CodeGenTypes::arrangeLLVMFunctionInfo(
- CanQualType resultType, FnInfoOpts opts, ArrayRef<CanQualType> argTypes,
- FunctionType::ExtInfo info,
- ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
- RequiredArgs required) {
+const CGFunctionInfo &
+CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
+ bool instanceMethod,
+ bool chainCall,
+ ArrayRef<CanQualType> argTypes,
+ FunctionType::ExtInfo info,
+ ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
+ RequiredArgs required) {
assert(llvm::all_of(argTypes,
[](CanQualType T) { return T.isCanonicalAsParam(); }));
// Lookup or create unique function info.
llvm::FoldingSetNodeID ID;
- bool isInstanceMethod =
- (opts & FnInfoOpts::IsInstanceMethod) == FnInfoOpts::IsInstanceMethod;
- bool isChainCall =
- (opts & FnInfoOpts::IsChainCall) == FnInfoOpts::IsChainCall;
- bool isDelegateCall =
- (opts & FnInfoOpts::IsDelegateCall) == FnInfoOpts::IsDelegateCall;
- CGFunctionInfo::Profile(ID, isInstanceMethod, isChainCall, isDelegateCall,
- info, paramInfos, required, resultType, argTypes);
+ CGFunctionInfo::Profile(ID, instanceMethod, chainCall, info, paramInfos,
+ required, resultType, argTypes);
void *insertPos = nullptr;
CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
@@ -774,8 +775,8 @@ const CGFunctionInfo &CodeGenTypes::arrangeLLVMFunctionInfo(
unsigned CC = ClangCallConvToLLVMCallConv(info.getCC());
// Construct the function info. We co-allocate the ArgInfos.
- FI = CGFunctionInfo::create(CC, isInstanceMethod, isChainCall, isDelegateCall,
- info, paramInfos, resultType, argTypes, required);
+ FI = CGFunctionInfo::create(CC, instanceMethod, chainCall, info,
+ paramInfos, resultType, argTypes, required);
FunctionInfos.InsertNode(FI, insertPos);
bool inserted = FunctionsBeingProcessed.insert(FI).second;
@@ -810,8 +811,9 @@ const CGFunctionInfo &CodeGenTypes::arrangeLLVMFunctionInfo(
return *FI;
}
-CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC, bool instanceMethod,
- bool chainCall, bool delegateCall,
+CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC,
+ bool instanceMethod,
+ bool chainCall,
const FunctionType::ExtInfo &info,
ArrayRef<ExtParameterInfo> paramInfos,
CanQualType resultType,
@@ -831,7 +833,6 @@ CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC, bool instanceMethod,
FI->ASTCallingConvention = info.getCC();
FI->InstanceMethod = instanceMethod;
FI->ChainCall = chainCall;
- FI->DelegateCall = delegateCall;
FI->CmseNSCall = info.getCmseNSCall();
FI->NoReturn = info.getNoReturn();
FI->ReturnsRetained = info.getProducesResult();
@@ -3984,6 +3985,10 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,
QualType type = param->getType();
+ if (isInAllocaArgument(CGM.getCXXABI(), type)) {
+ CGM.ErrorUnsupported(param, "forwarded non-trivially copyable parameter");
+ }
+
// GetAddrOfLocalVar returns a pointer-to-pointer for references,
// but the argument needs to be the original pointer.
if (type->isReferenceType()) {
diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h
index 1cf2cd6cf28b1..824f0a9a88299 100644
--- a/clang/lib/CodeGen/CGCall.h
+++ b/clang/lib/CodeGen/CGCall.h
@@ -386,35 +386,6 @@ void mergeDefaultFunctionDefinitionAttributes(llvm::Function &F,
const TargetOptions &TargetOpts,
bool WillInternalize);
-enum class FnInfoOpts {
- None = 0,
- IsInstanceMethod = 1 << 0,
- IsChainCall = 1 << 1,
- IsDelegateCall = 1 << 2,
-};
-
-inline FnInfoOpts operator|(FnInfoOpts A, FnInfoOpts B) {
- return static_cast<FnInfoOpts>(
- static_cast<std::underlying_type_t<FnInfoOpts>>(A) |
- static_cast<std::underlying_type_t<FnInfoOpts>>(B));
-}
-
-inline FnInfoOpts operator&(FnInfoOpts A, FnInfoOpts B) {
- return static_cast<FnInfoOpts>(
- static_cast<std::underlying_type_t<FnInfoOpts>>(A) &
- static_cast<std::underlying_type_t<FnInfoOpts>>(B));
-}
-
-inline FnInfoOpts operator|=(FnInfoOpts A, FnInfoOpts B) {
- A = A | B;
- return A;
-}
-
-inline FnInfoOpts operator&=(FnInfoOpts A, FnInfoOpts B) {
- A = A & B;
- return A;
-}
-
} // end namespace CodeGen
} // end namespace clang
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 40fb9bbbe8952..4bc8001d9605d 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2929,16 +2929,14 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
}
void CodeGenFunction::EmitForwardingCallToLambda(
- const CXXMethodDecl *callOperator, CallArgList &callArgs,
- const CGFunctionInfo *calleeFnInfo, llvm::Constant *calleePtr) {
+ const CXXMethodDecl *callOperator,
+ CallArgList &callArgs) {
// Get the address of the call operator.
- if (!calleeFnInfo)
- calleeFnInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
-
- if (!calleePtr)
- calleePtr =
- CGM.GetAddrOfFunction(GlobalDecl(callOperator),
- CGM.getTypes().GetFunctionType(*calleeFnInfo));
+ const CGFunctionInfo &calleeFnInfo =
+ CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
+ llvm::Constant *calleePtr =
+ CGM.GetAddrOfFunction(GlobalDecl(callOperator),
+ CGM.getTypes().GetFunctionType(calleeFnInfo));
// Prepare the return slot.
const FunctionProtoType *FPT =
@@ -2946,8 +2944,8 @@ void CodeGenFunction::EmitForwardingCallToLambda(
QualType resultType = FPT->getReturnType();
ReturnValueSlot returnSlot;
if (!resultType->isVoidType() &&
- calleeFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
- !hasScalarEvaluationKind(calleeFnInfo->getReturnType()))
+ calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect &&
+ !hasScalarEvaluationKind(calleeFnInfo.getReturnType()))
returnSlot =
ReturnValueSlot(ReturnValue, resultType.isVolatileQualified(),
/*IsUnused=*/false, /*IsExternallyDestructed=*/true);
@@ -2958,7 +2956,7 @@ void CodeGenFunction::EmitForwardingCallToLambda(
// 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);
// If necessary, copy the returned value into the slot.
if (!resultType->isVoidType() && returnSlot.isNull()) {
@@ -3000,15 +2998,7 @@ void CodeGenFunction::EmitLambdaBlockInvokeBody() {
EmitForwardingCallToLambda(CallOp, CallArgs);
}
-void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) {
- if (MD->isVariadic()) {
- // FIXME: Making this work correctly is nasty because it requires either
- // cloning the body of the call operator or making the call operator
- // forward.
- CGM.ErrorUnsupported(MD, "lambda conversion to variadic function");
- return;
- }
-
+void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {
const CXXRecordDecl *Lambda = MD->getParent();
// Start building arguments for forwarding call
@@ -3019,16 +3009,10 @@ void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) {
Address ThisPtr = CreateMemTemp(LambdaType, "unused.capture");
CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType);
- EmitLambdaDelegatingInvokeBody(MD, CallArgs);
-}
-
-void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD,
- CallArgList &CallArgs) {
- // Add the rest of the forwarded parameters.
+ // Add the rest of the parameters.
for (auto *Param : MD->parameters())
EmitDelegateCallArg(CallArgs, Param, Param->getBeginLoc());
- const CXXRecordDecl *Lambda = MD->getParent();
const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator();
// For a generic lambda, find the corresponding call operator specialization
// to which the call to the static-invoker shall be forwarded.
@@ -3042,21 +3026,10 @@ void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD,
assert(CorrespondingCallOpSpecialization);
CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
}
-
- // Special lambda forwarding when there are inalloca parameters.
- if (hasInAllocaArg(MD)) {
- const CGFunctionInfo *ImplFnInfo = nullptr;
- llvm::Function *ImplFn = nullptr;
- EmitLambdaInAllocaImplFn(CallOp, &ImplFnInfo, &ImplFn);
-
- EmitForwardingCallToLambda(CallOp, CallArgs, ImplFnInfo, ImplFn);
- return;
- }
-
EmitForwardingCallToLambda(CallOp, CallArgs);
}
-void CodeGenFunction::EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD) {
+void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) {
if (MD->isVariadic()) {
// FIXME: Making this work correctly is nasty because it requires either
// cloning the body of the call operator or making the call operator forward.
@@ -3064,49 +3037,5 @@ void CodeGenFunction::EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD) {
return;
}
- // Forward %this argument.
- CallArgList CallArgs;
- QualType LambdaType = getContext().getRecordType(MD->getParent());
- QualType ThisType = getContext().getPointerType(LambdaType);
- llvm::Value *ThisArg = CurFn->getArg(0);
- CallArgs.add(RValue::get(ThisArg), ThisType);
-
- EmitLambdaDelegatingInvokeBody(MD, CallArgs);
-}
-
-void CodeGenFunction::EmitLambdaInAllocaImplFn(
- const CXXMethodDecl *CallOp, const CGFunctionInfo **ImplFnInfo,
- llvm::Function **ImplFn) {
- const CGFunctionInfo &FnInfo =
- CGM.getTypes().arrangeCXXMethodDeclaration(CallOp);
- llvm::Function *CallOpFn =
- cast<llvm::Function>(CGM.GetAddrOfFunction(GlobalDecl(CallOp)));
-
- // Emit function containing the original call op body. __invoke will delegate
- // to this function.
- SmallVector<CanQualType, 4> ArgTypes;
- for (auto I = FnInfo.arg_begin(); I != FnInfo.arg_end(); ++I)
- ArgTypes.push_back(I->type);
- *ImplFnInfo = &CGM.getTypes().arrangeLLVMFunctionInfo(
- FnInfo.getReturnType(), FnInfoOpts::IsDelegateCall, ArgTypes,
- FnInfo.getExtInfo(), {}, FnInfo.getRequiredArgs());
-
- // Create mangled name as if this was a method named __impl.
- StringRef CallOpName = CallOpFn->getName();
- std::string ImplName =
- ("?__impl@" + CallOpName.drop_front(CallOpName.find_first_of("<"))).str();
-
- llvm::Function *Fn = CallOpFn->getParent()->getFunction(ImplName);
- if (!Fn) {
- Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(**ImplFnInfo),
- llvm::GlobalValue::InternalLinkage, ImplName,
- CGM.getModule());
- CGM.SetInternalFunctionAttributes(CallOp, Fn, **ImplFnInfo);
-
- const GlobalDecl &GD = GlobalDecl(CallOp);
- const auto *D = cast<FunctionDecl>(GD.getDecl());
- CodeGenFunction(CGM).GenerateCode(GD, Fn, **ImplFnInfo);
- CGM.SetLLVMFunctionAttributesForDefinition(D, Fn);
- }
- *ImplFn = Fn;
+ EmitLambdaDelegatingInvokeBody(MD);
}
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 772d5cf30b1c6..8a77ffeed52f7 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -279,8 +279,8 @@ llvm::Function *CodeGenFunction::createTLSAtExitStub(
}
const CGFunctionInfo &FI = CGM.getTypes().arrangeLLVMFunctionInfo(
- getContext().IntTy, FnInfoOpts::None, {getContext().IntTy},
- FunctionType::ExtInfo(), {}, RequiredArgs::All);
+ getContext().IntTy, /*instanceMethod=*/false, /*chainCall=*/false,
+ {getContext().IntTy}, FunctionType::ExtInfo(), {}, RequiredArgs::All);
// Get the stub function type, int(*)(int,...).
llvm::FunctionType *StubTy =
diff --git a/clang/lib/CodeGen/CodeGenABITypes.cpp b/clang/lib/CodeGen/CodeGenABITypes.cpp
index a6073e1188d6f..d3a16a1d5accf 100644
--- a/clang/lib/CodeGen/CodeGenABITypes.cpp
+++ b/clang/lib/CodeGen/CodeGenABITypes.cpp
@@ -65,8 +65,9 @@ CodeGen::arrangeFreeFunctionCall(CodeGenModule &CGM,
ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
RequiredArgs args) {
- return CGM.getTypes().arrangeLLVMFunctionInfo(returnType, FnInfoOpts::None,
- argTypes, info, {}, args);
+ return CGM.getTypes().arrangeLLVMFunctionInfo(
+ returnType, /*instanceMethod=*/false, /*chainCall=*/false, argTypes,
+ info, {}, args);
}
ImplicitCXXConstructorArgs
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 6899388a842db..b8d39371a9330 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -683,19 +683,6 @@ static bool matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx) {
return true;
}
-bool CodeGenFunction::isInAllocaArgument(CGCXXABI &ABI, QualType Ty) {
- const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
- return RD && ABI.getRecordArgABI(RD) == CGCXXABI::RAA_DirectInMemory;
-}
-
-bool CodeGenFunction::hasInAllocaArg(const CXXMethodDecl *MD) {
- return getTarget().getTriple().getArch() == llvm::Triple::x86 &&
- getTarget().getCXXABI().isMicrosoft() &&
- llvm::any_of(MD->parameters(), [&](ParmVarDecl *P) {
- return isInAllocaArgument(CGM.getCXXABI(), P->getType());
- });
-}
-
/// Return the UBSan prologue signature for \p FD if one is available.
static llvm::Constant *getPrologueSignature(CodeGenModule &CGM,
const FunctionDecl *FD) {
@@ -1460,17 +1447,6 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn,
// The lambda static invoker function is special, because it forwards or
// clones the body of the function call operator (but is actually static).
EmitLambdaStaticInvokeBody(cast<CXXMethodDecl>(FD));
-
- } else if (isa<CXXMethodDecl>(FD) &&
- isLambdaCallOperator(cast<CXXMethodDecl>(FD)) &&
- cast<CXXMethodDecl>(FD)->getParent()->getLambdaStaticInvoker() &&
- hasInAllocaArg(cast<CXXMethodDecl>(FD)
- ->getParent()
- ->getLambdaStaticInvoker()) &&
- !FnInfo.isDelegateCall()) {
- // If emitting a lambda with static invoker on X86 Windows, change
- // the call operator body.
- EmitLambdaInAllocaCallOpBody(cast<CXXMethodDecl>(FD));
} else if (FD->isDefaulted() && isa<CXXMethodDecl>(FD) &&
(cast<CXXMethodDecl>(FD)->isCopyAssignmentOperator() ||
cast<CXXMethodDecl>(FD)->isMoveAssignmentOperator())) {
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 09a8c0779c460..0f720596165ff 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1963,9 +1963,6 @@ class CodeGenFunction : public CodeGenTypeCache {
/// Check if the return value of this function requires sanitization.
bool requiresReturnValueCheck() const;
- bool isInAllocaArgument(CGCXXABI &ABI, QualType Ty);
- bool hasInAllocaArg(const CXXMethodDecl *MD);
-
llvm::BasicBlock *TerminateLandingPad = nullptr;
llvm::BasicBlock *TerminateHandler = nullptr;
llvm::SmallVector<llvm::BasicBlock *, 2> TrapBBs;
@@ -2228,17 +2225,10 @@ class CodeGenFunction : public CodeGenTypeCache {
void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S);
void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator,
- CallArgList &CallArgs,
- const CGFunctionInfo *CallOpFnInfo = nullptr,
- llvm::Constant *CallOpFn = nullptr);
+ CallArgList &CallArgs);
void EmitLambdaBlockInvokeBody();
+ void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD);
void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD);
- void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD,
- CallArgList &CallArgs);
- void EmitLambdaInAllocaImplFn(const CXXMethodDecl *CallOp,
- const CGFunctionInfo **ImplFnInfo,
- llvm::Function **ImplFn);
- void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD);
void EmitLambdaVLACapture(const VariableArrayType *VAT, LValue LV) {
EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
}
diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h
index a0e846d9a7516..9088f77b95c34 100644
--- a/clang/lib/CodeGen/CodeGenTypes.h
+++ b/clang/lib/CodeGen/CodeGenTypes.h
@@ -252,11 +252,13 @@ class CodeGenTypes {
/// this.
///
/// \param argTypes - must all actually be canonical as params
- const CGFunctionInfo &arrangeLLVMFunctionInfo(
- CanQualType returnType, FnInfoOpts opts, ArrayRef<CanQualType> argTypes,
- FunctionType::ExtInfo info,
- ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
- RequiredArgs args);
+ const CGFunctionInfo &arrangeLLVMFunctionInfo(CanQualType returnType,
+ bool instanceMethod,
+ bool chainCall,
+ ArrayRef<CanQualType> argTypes,
+ FunctionType::ExtInfo info,
+ ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
+ RequiredArgs args);
/// Compute a new LLVM record layout object for the given record.
std::unique_ptr<CGRecordLayout> ComputeRecordLayout(const RecordDecl *D,
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index f48410d565151..d08e7cef5bce4 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -140,8 +140,7 @@ class X86_32ABIInfo : public ABIInfo {
Class classify(QualType Ty) const;
ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const;
- ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State,
- bool isDelegateCall) const;
+ ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const;
/// Updates the number of available free registers, returns
/// true if any registers were allocated.
@@ -739,8 +738,8 @@ void X86_32ABIInfo::runVectorCallFirstPass(CGFunctionInfo &FI, CCState &State) c
}
}
-ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State,
- bool isDelegateCall) const {
+ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
+ CCState &State) const {
// FIXME: Set alignment on indirect arguments.
bool IsFastCall = State.CC == llvm::CallingConv::X86_FastCall;
bool IsRegCall = State.CC == llvm::CallingConv::X86_RegCall;
@@ -753,7 +752,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State,
const RecordType *RT = Ty->getAs<RecordType>();
if (RT) {
CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI());
- if (RAA == CGCXXABI::RAA_Indirect || isDelegateCall) {
+ if (RAA == CGCXXABI::RAA_Indirect) {
return getIndirectResult(Ty, false, State);
} else if (RAA == CGCXXABI::RAA_DirectInMemory) {
// The field index doesn't matter, we'll fix it up later.
@@ -942,8 +941,7 @@ void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
if (State.IsPreassigned.test(I))
continue;
- Args[I].info =
- classifyArgumentType(Args[I].type, State, FI.isDelegateCall());
+ Args[I].info = classifyArgumentType(Args[I].type, State);
UsedInAlloca |= (Args[I].info.getKind() == ABIArgInfo::InAlloca);
}
diff --git a/clang/test/CodeGenCXX/inalloca-lambda.cpp b/clang/test/CodeGenCXX/inalloca-lambda.cpp
index 19b20fe055f02..ac85ee175268b 100644
--- a/clang/test/CodeGenCXX/inalloca-lambda.cpp
+++ b/clang/test/CodeGenCXX/inalloca-lambda.cpp
@@ -1,50 +1,11 @@
-// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -o - %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple i686-windows-msvc -emit-llvm -o /dev/null %s 2>&1 | FileCheck %s
-struct A {
- A();
+// PR28299
+// CHECK: error: cannot compile this forwarded non-trivially copyable parameter yet
+
+class A {
A(const A &);
- int x;
};
-void decayToFp(int (*f)(A));
-void test() {
- auto ld = [](A a) {
- static int calls = 0;
- ++calls;
- return a.x + calls;
- };
- decayToFp(ld);
- ld(A{});
-}
-
-// CHECK: define internal x86_thiscallcc noundef i32
-// CHECK-SAME: @"??R<lambda_0>@?0??test@@YAXXZ at QBE?A?<auto>@@UA@@@Z"
-// CHECK-SAME: (ptr noundef %this, ptr inalloca(<{ %struct.A }>) %[[ARG:.*]])
-// CHECK: %[[V:.*]] = getelementptr inbounds <{ %struct.A }>, ptr %[[ARG]], i32 0, i32 0
-// CHECK: %call = call x86_thiscallcc noundef i32
-// CHECK-SAME: @"?__impl@<lambda_0>@?0??test@@YAXXZ at QBE?A?<auto>@@UA@@@Z"
-// CHECK-SAME: (ptr noundef %this, ptr noundef %[[V]])
-
-// CHECK: define internal noundef i32
-// CHECK-SAME: @"?__invoke@<lambda_0>@?0??test@@YAXXZ at CA?A?<auto>@@UA@@@Z"
-// CHECK-SAME: (ptr inalloca(<{ %struct.A }>) %[[ARG:.*]])
-// CHECK: %unused.capture = alloca %class.anon, align 1
-// CHECK: %[[VAR:.*]] = getelementptr inbounds <{ %struct.A }>, ptr %[[ARG]], i32 0, i32 0
-// CHECK: %call = call x86_thiscallcc noundef i32
-// CHECK-SAME: @"?__impl@<lambda_0>@?0??test@@YAXXZ at QBE?A?<auto>@@UA@@@Z"
-// CHECK-SAME: (ptr noundef %unused.capture, ptr noundef %[[VAR]])
-// CHECK: ret i32 %call
+typedef void (*fptr_t)(A);
+fptr_t fn1() { return [](A) {}; }
-// CHECK: define internal x86_thiscallcc noundef i32
-// CHECK-SAME: @"?__impl@<lambda_0>@?0??test@@YAXXZ at QBE?A?<auto>@@UA@@@Z"
-// CHECK-SAME: (ptr noundef %this, ptr noundef %[[ARG:.*]])
-// CHECK: %this.addr = alloca ptr, align 4
-// CHECK: store ptr %this, ptr %this.addr, align 4
-// CHECK: %this1 = load ptr, ptr %this.addr, align 4
-// CHECK: %{{.*}} = load i32, ptr @"?calls@?1???R<lambda_0>
-// CHECK: %inc = add nsw i32 %{{.*}}, 1
-// CHECK: store i32 %inc, ptr @"?calls@?1???R<lambda_0>
-// CHECK: %{{.*}} = getelementptr inbounds %struct.A, ptr %{{.*}}, i32 0, i32 0
-// CHECK: %{{.*}} = load i32, ptr %{{.*}}, align 4
-// CHECK: %{{.*}} = load i32, ptr @"?calls@?1???R<lambda_0>
-// CHECK: %add = add nsw i32 %{{.*}}, %{{.*}}
-// CHECK: ret i32 %add
More information about the cfe-commits
mailing list