[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