1f22ef01cSRoman Divacky //===--- CGExprCXX.cpp - Emit LLVM Code for C++ expressions ---------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This contains code dealing with code generation of C++ expressions
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
14f22ef01cSRoman Divacky #include "CodeGenFunction.h"
156122f3e6SDimitry Andric #include "CGCUDARuntime.h"
16e580952dSDimitry Andric #include "CGCXXABI.h"
172754fe60SDimitry Andric #include "CGDebugInfo.h"
18139f7f9bSDimitry Andric #include "CGObjCRuntime.h"
199a199699SDimitry Andric #include "ConstantEmitter.h"
20*b5893f02SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
21f785676fSDimitry Andric #include "clang/CodeGen/CGFunctionInfo.h"
2259d1ed5bSDimitry Andric #include "llvm/IR/CallSite.h"
23139f7f9bSDimitry Andric #include "llvm/IR/Intrinsics.h"
243b0f4066SDimitry Andric 
25f22ef01cSRoman Divacky using namespace clang;
26f22ef01cSRoman Divacky using namespace CodeGen;
27f22ef01cSRoman Divacky 
2820e90f04SDimitry Andric namespace {
2920e90f04SDimitry Andric struct MemberCallInfo {
3020e90f04SDimitry Andric   RequiredArgs ReqArgs;
3120e90f04SDimitry Andric   // Number of prefix arguments for the call. Ignores the `this` pointer.
3220e90f04SDimitry Andric   unsigned PrefixSize;
3320e90f04SDimitry Andric };
3420e90f04SDimitry Andric }
3520e90f04SDimitry Andric 
3620e90f04SDimitry Andric static MemberCallInfo
commonEmitCXXMemberOrOperatorCall(CodeGenFunction & CGF,const CXXMethodDecl * MD,llvm::Value * This,llvm::Value * ImplicitParam,QualType ImplicitParamTy,const CallExpr * CE,CallArgList & Args,CallArgList * RtlArgs)37e7145dcbSDimitry Andric commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, const CXXMethodDecl *MD,
38e7145dcbSDimitry Andric                                   llvm::Value *This, llvm::Value *ImplicitParam,
39e7145dcbSDimitry Andric                                   QualType ImplicitParamTy, const CallExpr *CE,
4044290647SDimitry Andric                                   CallArgList &Args, CallArgList *RtlArgs) {
4139d628a0SDimitry Andric   assert(CE == nullptr || isa<CXXMemberCallExpr>(CE) ||
4239d628a0SDimitry Andric          isa<CXXOperatorCallExpr>(CE));
43f22ef01cSRoman Divacky   assert(MD->isInstance() &&
4439d628a0SDimitry Andric          "Trying to emit a member or operator call expr on a static method!");
4544290647SDimitry Andric   ASTContext &C = CGF.getContext();
46f22ef01cSRoman Divacky 
47f22ef01cSRoman Divacky   // Push the this ptr.
4844290647SDimitry Andric   const CXXRecordDecl *RD =
4944290647SDimitry Andric       CGF.CGM.getCXXABI().getThisArgumentTypeForMethod(MD);
5044290647SDimitry Andric   Args.add(RValue::get(This),
5144290647SDimitry Andric            RD ? C.getPointerType(C.getTypeDeclType(RD)) : C.VoidPtrTy);
52f22ef01cSRoman Divacky 
53139f7f9bSDimitry Andric   // If there is an implicit parameter (e.g. VTT), emit it.
54139f7f9bSDimitry Andric   if (ImplicitParam) {
55139f7f9bSDimitry Andric     Args.add(RValue::get(ImplicitParam), ImplicitParamTy);
56f22ef01cSRoman Divacky   }
57f22ef01cSRoman Divacky 
58dff0c46cSDimitry Andric   const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
59e7145dcbSDimitry Andric   RequiredArgs required = RequiredArgs::forPrototypePlus(FPT, Args.size(), MD);
6020e90f04SDimitry Andric   unsigned PrefixSize = Args.size() - 1;
61dff0c46cSDimitry Andric 
62dff0c46cSDimitry Andric   // And the rest of the call args.
6344290647SDimitry Andric   if (RtlArgs) {
6444290647SDimitry Andric     // Special case: if the caller emitted the arguments right-to-left already
6544290647SDimitry Andric     // (prior to emitting the *this argument), we're done. This happens for
6644290647SDimitry Andric     // assignment operators.
6744290647SDimitry Andric     Args.addFrom(*RtlArgs);
6844290647SDimitry Andric   } else if (CE) {
6939d628a0SDimitry Andric     // Special case: skip first argument of CXXOperatorCall (it is "this").
7039d628a0SDimitry Andric     unsigned ArgsToSkip = isa<CXXOperatorCallExpr>(CE) ? 1 : 0;
710623d748SDimitry Andric     CGF.EmitCallArgs(Args, FPT, drop_begin(CE->arguments(), ArgsToSkip),
7239d628a0SDimitry Andric                      CE->getDirectCallee());
7339d628a0SDimitry Andric   } else {
7439d628a0SDimitry Andric     assert(
7539d628a0SDimitry Andric         FPT->getNumParams() == 0 &&
7639d628a0SDimitry Andric         "No CallExpr specified for function with non-zero number of arguments");
7739d628a0SDimitry Andric   }
7820e90f04SDimitry Andric   return {required, PrefixSize};
7939d628a0SDimitry Andric }
80f22ef01cSRoman Divacky 
EmitCXXMemberOrOperatorCall(const CXXMethodDecl * MD,const CGCallee & Callee,ReturnValueSlot ReturnValue,llvm::Value * This,llvm::Value * ImplicitParam,QualType ImplicitParamTy,const CallExpr * CE,CallArgList * RtlArgs)8139d628a0SDimitry Andric RValue CodeGenFunction::EmitCXXMemberOrOperatorCall(
8244290647SDimitry Andric     const CXXMethodDecl *MD, const CGCallee &Callee,
8344290647SDimitry Andric     ReturnValueSlot ReturnValue,
8439d628a0SDimitry Andric     llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy,
8544290647SDimitry Andric     const CallExpr *CE, CallArgList *RtlArgs) {
8639d628a0SDimitry Andric   const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
8739d628a0SDimitry Andric   CallArgList Args;
8820e90f04SDimitry Andric   MemberCallInfo CallInfo = commonEmitCXXMemberOrOperatorCall(
8944290647SDimitry Andric       *this, MD, This, ImplicitParam, ImplicitParamTy, CE, Args, RtlArgs);
9020e90f04SDimitry Andric   auto &FnInfo = CGM.getTypes().arrangeCXXMethodCall(
9120e90f04SDimitry Andric       Args, FPT, CallInfo.ReqArgs, CallInfo.PrefixSize);
9213ddaa84SDimitry Andric   return EmitCall(FnInfo, Callee, ReturnValue, Args, nullptr,
9313ddaa84SDimitry Andric                   CE ? CE->getExprLoc() : SourceLocation());
94f22ef01cSRoman Divacky }
95f22ef01cSRoman Divacky 
EmitCXXDestructorCall(const CXXDestructorDecl * DD,const CGCallee & Callee,llvm::Value * This,llvm::Value * ImplicitParam,QualType ImplicitParamTy,const CallExpr * CE,StructorType Type)96e7145dcbSDimitry Andric RValue CodeGenFunction::EmitCXXDestructorCall(
9744290647SDimitry Andric     const CXXDestructorDecl *DD, const CGCallee &Callee, llvm::Value *This,
98e7145dcbSDimitry Andric     llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *CE,
99e7145dcbSDimitry Andric     StructorType Type) {
10039d628a0SDimitry Andric   CallArgList Args;
101e7145dcbSDimitry Andric   commonEmitCXXMemberOrOperatorCall(*this, DD, This, ImplicitParam,
10244290647SDimitry Andric                                     ImplicitParamTy, CE, Args, nullptr);
103e7145dcbSDimitry Andric   return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(DD, Type),
10444290647SDimitry Andric                   Callee, ReturnValueSlot(), Args);
10544290647SDimitry Andric }
10644290647SDimitry Andric 
EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr * E)10744290647SDimitry Andric RValue CodeGenFunction::EmitCXXPseudoDestructorExpr(
10844290647SDimitry Andric                                             const CXXPseudoDestructorExpr *E) {
10944290647SDimitry Andric   QualType DestroyedType = E->getDestroyedType();
11044290647SDimitry Andric   if (DestroyedType.hasStrongOrWeakObjCLifetime()) {
11144290647SDimitry Andric     // Automatic Reference Counting:
11244290647SDimitry Andric     //   If the pseudo-expression names a retainable object with weak or
11344290647SDimitry Andric     //   strong lifetime, the object shall be released.
11444290647SDimitry Andric     Expr *BaseExpr = E->getBase();
11544290647SDimitry Andric     Address BaseValue = Address::invalid();
11644290647SDimitry Andric     Qualifiers BaseQuals;
11744290647SDimitry Andric 
11844290647SDimitry Andric     // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
11944290647SDimitry Andric     if (E->isArrow()) {
12044290647SDimitry Andric       BaseValue = EmitPointerWithAlignment(BaseExpr);
12144290647SDimitry Andric       const PointerType *PTy = BaseExpr->getType()->getAs<PointerType>();
12244290647SDimitry Andric       BaseQuals = PTy->getPointeeType().getQualifiers();
12344290647SDimitry Andric     } else {
12444290647SDimitry Andric       LValue BaseLV = EmitLValue(BaseExpr);
12544290647SDimitry Andric       BaseValue = BaseLV.getAddress();
12644290647SDimitry Andric       QualType BaseTy = BaseExpr->getType();
12744290647SDimitry Andric       BaseQuals = BaseTy.getQualifiers();
12844290647SDimitry Andric     }
12944290647SDimitry Andric 
13044290647SDimitry Andric     switch (DestroyedType.getObjCLifetime()) {
13144290647SDimitry Andric     case Qualifiers::OCL_None:
13244290647SDimitry Andric     case Qualifiers::OCL_ExplicitNone:
13344290647SDimitry Andric     case Qualifiers::OCL_Autoreleasing:
13444290647SDimitry Andric       break;
13544290647SDimitry Andric 
13644290647SDimitry Andric     case Qualifiers::OCL_Strong:
13744290647SDimitry Andric       EmitARCRelease(Builder.CreateLoad(BaseValue,
13844290647SDimitry Andric                         DestroyedType.isVolatileQualified()),
13944290647SDimitry Andric                      ARCPreciseLifetime);
14044290647SDimitry Andric       break;
14144290647SDimitry Andric 
14244290647SDimitry Andric     case Qualifiers::OCL_Weak:
14344290647SDimitry Andric       EmitARCDestroyWeak(BaseValue);
14444290647SDimitry Andric       break;
14544290647SDimitry Andric     }
14644290647SDimitry Andric   } else {
14744290647SDimitry Andric     // C++ [expr.pseudo]p1:
14844290647SDimitry Andric     //   The result shall only be used as the operand for the function call
14944290647SDimitry Andric     //   operator (), and the result of such a call has type void. The only
15044290647SDimitry Andric     //   effect is the evaluation of the postfix-expression before the dot or
15144290647SDimitry Andric     //   arrow.
15244290647SDimitry Andric     EmitIgnoredExpr(E->getBase());
15344290647SDimitry Andric   }
15444290647SDimitry Andric 
15544290647SDimitry Andric   return RValue::get(nullptr);
15639d628a0SDimitry Andric }
15739d628a0SDimitry Andric 
getCXXRecord(const Expr * E)1587ae0e2c9SDimitry Andric static CXXRecordDecl *getCXXRecord(const Expr *E) {
1597ae0e2c9SDimitry Andric   QualType T = E->getType();
1607ae0e2c9SDimitry Andric   if (const PointerType *PTy = T->getAs<PointerType>())
1617ae0e2c9SDimitry Andric     T = PTy->getPointeeType();
1627ae0e2c9SDimitry Andric   const RecordType *Ty = T->castAs<RecordType>();
1637ae0e2c9SDimitry Andric   return cast<CXXRecordDecl>(Ty->getDecl());
1647ae0e2c9SDimitry Andric }
1657ae0e2c9SDimitry Andric 
1662754fe60SDimitry Andric // Note: This function also emit constructor calls to support a MSVC
1672754fe60SDimitry Andric // extensions allowing explicit constructor function call.
EmitCXXMemberCallExpr(const CXXMemberCallExpr * CE,ReturnValueSlot ReturnValue)168f22ef01cSRoman Divacky RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
169f22ef01cSRoman Divacky                                               ReturnValueSlot ReturnValue) {
1703b0f4066SDimitry Andric   const Expr *callee = CE->getCallee()->IgnoreParens();
1713b0f4066SDimitry Andric 
1723b0f4066SDimitry Andric   if (isa<BinaryOperator>(callee))
173f22ef01cSRoman Divacky     return EmitCXXMemberPointerCallExpr(CE, ReturnValue);
174f22ef01cSRoman Divacky 
1753b0f4066SDimitry Andric   const MemberExpr *ME = cast<MemberExpr>(callee);
176f22ef01cSRoman Divacky   const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
177f22ef01cSRoman Divacky 
178f22ef01cSRoman Divacky   if (MD->isStatic()) {
179f22ef01cSRoman Divacky     // The method is static, emit it as we would a regular call.
180*b5893f02SDimitry Andric     CGCallee callee =
181*b5893f02SDimitry Andric         CGCallee::forDirect(CGM.GetAddrOfFunction(MD), GlobalDecl(MD));
18244290647SDimitry Andric     return EmitCall(getContext().getPointerType(MD->getType()), callee, CE,
18339d628a0SDimitry Andric                     ReturnValue);
184f22ef01cSRoman Divacky   }
185f22ef01cSRoman Divacky 
18639d628a0SDimitry Andric   bool HasQualifier = ME->hasQualifier();
18739d628a0SDimitry Andric   NestedNameSpecifier *Qualifier = HasQualifier ? ME->getQualifier() : nullptr;
18839d628a0SDimitry Andric   bool IsArrow = ME->isArrow();
1897ae0e2c9SDimitry Andric   const Expr *Base = ME->getBase();
19039d628a0SDimitry Andric 
19139d628a0SDimitry Andric   return EmitCXXMemberOrOperatorMemberCallExpr(
19239d628a0SDimitry Andric       CE, MD, ReturnValue, HasQualifier, Qualifier, IsArrow, Base);
19339d628a0SDimitry Andric }
19439d628a0SDimitry Andric 
EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr * CE,const CXXMethodDecl * MD,ReturnValueSlot ReturnValue,bool HasQualifier,NestedNameSpecifier * Qualifier,bool IsArrow,const Expr * Base)19539d628a0SDimitry Andric RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
19639d628a0SDimitry Andric     const CallExpr *CE, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue,
19739d628a0SDimitry Andric     bool HasQualifier, NestedNameSpecifier *Qualifier, bool IsArrow,
19839d628a0SDimitry Andric     const Expr *Base) {
19939d628a0SDimitry Andric   assert(isa<CXXMemberCallExpr>(CE) || isa<CXXOperatorCallExpr>(CE));
20039d628a0SDimitry Andric 
20139d628a0SDimitry Andric   // Compute the object pointer.
20239d628a0SDimitry Andric   bool CanUseVirtualCall = MD->isVirtual() && !HasQualifier;
2037ae0e2c9SDimitry Andric 
20459d1ed5bSDimitry Andric   const CXXMethodDecl *DevirtualizedMethod = nullptr;
205c4394386SDimitry Andric   if (CanUseVirtualCall &&
206c4394386SDimitry Andric       MD->getDevirtualizedMethod(Base, getLangOpts().AppleKext)) {
2077ae0e2c9SDimitry Andric     const CXXRecordDecl *BestDynamicDecl = Base->getBestDynamicClassType();
2087ae0e2c9SDimitry Andric     DevirtualizedMethod = MD->getCorrespondingMethodInClass(BestDynamicDecl);
2097ae0e2c9SDimitry Andric     assert(DevirtualizedMethod);
2107ae0e2c9SDimitry Andric     const CXXRecordDecl *DevirtualizedClass = DevirtualizedMethod->getParent();
2117ae0e2c9SDimitry Andric     const Expr *Inner = Base->ignoreParenBaseCasts();
21239d628a0SDimitry Andric     if (DevirtualizedMethod->getReturnType().getCanonicalType() !=
21339d628a0SDimitry Andric         MD->getReturnType().getCanonicalType())
21439d628a0SDimitry Andric       // If the return types are not the same, this might be a case where more
21539d628a0SDimitry Andric       // code needs to run to compensate for it. For example, the derived
21639d628a0SDimitry Andric       // method might return a type that inherits form from the return
21739d628a0SDimitry Andric       // type of MD and has a prefix.
21839d628a0SDimitry Andric       // For now we just avoid devirtualizing these covariant cases.
21939d628a0SDimitry Andric       DevirtualizedMethod = nullptr;
22039d628a0SDimitry Andric     else if (getCXXRecord(Inner) == DevirtualizedClass)
2217ae0e2c9SDimitry Andric       // If the class of the Inner expression is where the dynamic method
2227ae0e2c9SDimitry Andric       // is defined, build the this pointer from it.
2237ae0e2c9SDimitry Andric       Base = Inner;
2247ae0e2c9SDimitry Andric     else if (getCXXRecord(Base) != DevirtualizedClass) {
2257ae0e2c9SDimitry Andric       // If the method is defined in a class that is not the best dynamic
2267ae0e2c9SDimitry Andric       // one or the one of the full expression, we would have to build
2277ae0e2c9SDimitry Andric       // a derived-to-base cast to compute the correct this pointer, but
2287ae0e2c9SDimitry Andric       // we don't have support for that yet, so do a virtual call.
22959d1ed5bSDimitry Andric       DevirtualizedMethod = nullptr;
2307ae0e2c9SDimitry Andric     }
2317ae0e2c9SDimitry Andric   }
2327ae0e2c9SDimitry Andric 
23344290647SDimitry Andric   // C++17 demands that we evaluate the RHS of a (possibly-compound) assignment
23444290647SDimitry Andric   // operator before the LHS.
23544290647SDimitry Andric   CallArgList RtlArgStorage;
23644290647SDimitry Andric   CallArgList *RtlArgs = nullptr;
23744290647SDimitry Andric   if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
23844290647SDimitry Andric     if (OCE->isAssignmentOp()) {
23944290647SDimitry Andric       RtlArgs = &RtlArgStorage;
24044290647SDimitry Andric       EmitCallArgs(*RtlArgs, MD->getType()->castAs<FunctionProtoType>(),
24144290647SDimitry Andric                    drop_begin(CE->arguments(), 1), CE->getDirectCallee(),
24244290647SDimitry Andric                    /*ParamsToSkip*/0, EvaluationOrder::ForceRightToLeft);
24344290647SDimitry Andric     }
24444290647SDimitry Andric   }
24544290647SDimitry Andric 
2464ba319b5SDimitry Andric   LValue This;
2474ba319b5SDimitry Andric   if (IsArrow) {
2484ba319b5SDimitry Andric     LValueBaseInfo BaseInfo;
2494ba319b5SDimitry Andric     TBAAAccessInfo TBAAInfo;
2504ba319b5SDimitry Andric     Address ThisValue = EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo);
2514ba319b5SDimitry Andric     This = MakeAddrLValue(ThisValue, Base->getType(), BaseInfo, TBAAInfo);
2524ba319b5SDimitry Andric   } else {
2534ba319b5SDimitry Andric     This = EmitLValue(Base);
2544ba319b5SDimitry Andric   }
2557ae0e2c9SDimitry Andric 
256f22ef01cSRoman Divacky 
25733956c43SDimitry Andric   if (MD->isTrivial() || (MD->isDefaulted() && MD->getParent()->isUnion())) {
25859d1ed5bSDimitry Andric     if (isa<CXXDestructorDecl>(MD)) return RValue::get(nullptr);
2592754fe60SDimitry Andric     if (isa<CXXConstructorDecl>(MD) &&
2602754fe60SDimitry Andric         cast<CXXConstructorDecl>(MD)->isDefaultConstructor())
26159d1ed5bSDimitry Andric       return RValue::get(nullptr);
262e580952dSDimitry Andric 
26339d628a0SDimitry Andric     if (!MD->getParent()->mayInsertExtraPadding()) {
2646122f3e6SDimitry Andric       if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()) {
2656122f3e6SDimitry Andric         // We don't like to generate the trivial copy/move assignment operator
2666122f3e6SDimitry Andric         // when it isn't necessary; just produce the proper effect here.
26744290647SDimitry Andric         LValue RHS = isa<CXXOperatorCallExpr>(CE)
26844290647SDimitry Andric                          ? MakeNaturalAlignAddrLValue(
2694ba319b5SDimitry Andric                                (*RtlArgs)[0].getRValue(*this).getScalarVal(),
27044290647SDimitry Andric                                (*(CE->arg_begin() + 1))->getType())
27144290647SDimitry Andric                          : EmitLValue(*CE->arg_begin());
2724ba319b5SDimitry Andric         EmitAggregateAssign(This, RHS, CE->getType());
2730623d748SDimitry Andric         return RValue::get(This.getPointer());
274f22ef01cSRoman Divacky       }
275f22ef01cSRoman Divacky 
2762754fe60SDimitry Andric       if (isa<CXXConstructorDecl>(MD) &&
2776122f3e6SDimitry Andric           cast<CXXConstructorDecl>(MD)->isCopyOrMoveConstructor()) {
2786122f3e6SDimitry Andric         // Trivial move and copy ctor are the same.
27939d628a0SDimitry Andric         assert(CE->getNumArgs() == 1 && "unexpected argcount for trivial ctor");
2804ba319b5SDimitry Andric         const Expr *Arg = *CE->arg_begin();
2814ba319b5SDimitry Andric         LValue RHS = EmitLValue(Arg);
2824ba319b5SDimitry Andric         LValue Dest = MakeAddrLValue(This.getAddress(), Arg->getType());
2834ba319b5SDimitry Andric         // This is the MSVC p->Ctor::Ctor(...) extension. We assume that's
2844ba319b5SDimitry Andric         // constructing a new complete object of type Ctor.
2854ba319b5SDimitry Andric         EmitAggregateCopy(Dest, RHS, Arg->getType(),
2864ba319b5SDimitry Andric                           AggValueSlot::DoesNotOverlap);
2870623d748SDimitry Andric         return RValue::get(This.getPointer());
2882754fe60SDimitry Andric       }
2892754fe60SDimitry Andric       llvm_unreachable("unknown trivial member function");
2902754fe60SDimitry Andric     }
29139d628a0SDimitry Andric   }
2922754fe60SDimitry Andric 
293e580952dSDimitry Andric   // Compute the function type we're calling.
29439d628a0SDimitry Andric   const CXXMethodDecl *CalleeDecl =
29539d628a0SDimitry Andric       DevirtualizedMethod ? DevirtualizedMethod : MD;
29659d1ed5bSDimitry Andric   const CGFunctionInfo *FInfo = nullptr;
29739d628a0SDimitry Andric   if (const auto *Dtor = dyn_cast<CXXDestructorDecl>(CalleeDecl))
29839d628a0SDimitry Andric     FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
29939d628a0SDimitry Andric         Dtor, StructorType::Complete);
30039d628a0SDimitry Andric   else if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(CalleeDecl))
30139d628a0SDimitry Andric     FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
30239d628a0SDimitry Andric         Ctor, StructorType::Complete);
3032754fe60SDimitry Andric   else
3043861d79fSDimitry Andric     FInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(CalleeDecl);
305e580952dSDimitry Andric 
306f785676fSDimitry Andric   llvm::FunctionType *Ty = CGM.getTypes().GetFunctionType(*FInfo);
307e580952dSDimitry Andric 
30844290647SDimitry Andric   // C++11 [class.mfct.non-static]p2:
30944290647SDimitry Andric   //   If a non-static member function of a class X is called for an object that
31044290647SDimitry Andric   //   is not of type X, or of a type derived from X, the behavior is undefined.
31144290647SDimitry Andric   SourceLocation CallLoc;
31244290647SDimitry Andric   ASTContext &C = getContext();
31344290647SDimitry Andric   if (CE)
31444290647SDimitry Andric     CallLoc = CE->getExprLoc();
31544290647SDimitry Andric 
31620e90f04SDimitry Andric   SanitizerSet SkippedChecks;
31720e90f04SDimitry Andric   if (const auto *CMCE = dyn_cast<CXXMemberCallExpr>(CE)) {
31820e90f04SDimitry Andric     auto *IOA = CMCE->getImplicitObjectArgument();
31920e90f04SDimitry Andric     bool IsImplicitObjectCXXThis = IsWrappedCXXThis(IOA);
32020e90f04SDimitry Andric     if (IsImplicitObjectCXXThis)
32120e90f04SDimitry Andric       SkippedChecks.set(SanitizerKind::Alignment, true);
32220e90f04SDimitry Andric     if (IsImplicitObjectCXXThis || isa<DeclRefExpr>(IOA))
32320e90f04SDimitry Andric       SkippedChecks.set(SanitizerKind::Null, true);
32420e90f04SDimitry Andric   }
32520e90f04SDimitry Andric   EmitTypeCheck(
32620e90f04SDimitry Andric       isa<CXXConstructorDecl>(CalleeDecl) ? CodeGenFunction::TCK_ConstructorCall
32744290647SDimitry Andric                                           : CodeGenFunction::TCK_MemberCall,
32820e90f04SDimitry Andric       CallLoc, This.getPointer(), C.getRecordType(CalleeDecl->getParent()),
32920e90f04SDimitry Andric       /*Alignment=*/CharUnits::Zero(), SkippedChecks);
33044290647SDimitry Andric 
33144290647SDimitry Andric   // FIXME: Uses of 'MD' past this point need to be audited. We may need to use
33244290647SDimitry Andric   // 'CalleeDecl' instead.
33344290647SDimitry Andric 
334f22ef01cSRoman Divacky   // C++ [class.virtual]p12:
335f22ef01cSRoman Divacky   //   Explicit qualification with the scope operator (5.1) suppresses the
336f22ef01cSRoman Divacky   //   virtual call mechanism.
337f22ef01cSRoman Divacky   //
338f22ef01cSRoman Divacky   // We also don't emit a virtual call if the base expression has a record type
339f22ef01cSRoman Divacky   // because then we know what the type is.
3407ae0e2c9SDimitry Andric   bool UseVirtualCall = CanUseVirtualCall && !DevirtualizedMethod;
341f785676fSDimitry Andric 
342e580952dSDimitry Andric   if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD)) {
343139f7f9bSDimitry Andric     assert(CE->arg_begin() == CE->arg_end() &&
344f785676fSDimitry Andric            "Destructor shouldn't have explicit parameters");
345f785676fSDimitry Andric     assert(ReturnValue.isNull() && "Destructor shouldn't have return value");
346f785676fSDimitry Andric     if (UseVirtualCall) {
34739d628a0SDimitry Andric       CGM.getCXXABI().EmitVirtualDestructorCall(
3484ba319b5SDimitry Andric           *this, Dtor, Dtor_Complete, This.getAddress(),
3494ba319b5SDimitry Andric           cast<CXXMemberCallExpr>(CE));
350f22ef01cSRoman Divacky     } else {
35144290647SDimitry Andric       CGCallee Callee;
35239d628a0SDimitry Andric       if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier)
35339d628a0SDimitry Andric         Callee = BuildAppleKextVirtualCall(MD, Qualifier, Ty);
3547ae0e2c9SDimitry Andric       else if (!DevirtualizedMethod)
35544290647SDimitry Andric         Callee = CGCallee::forDirect(
35644290647SDimitry Andric             CGM.getAddrOfCXXStructor(Dtor, StructorType::Complete, FInfo, Ty),
357*b5893f02SDimitry Andric             GlobalDecl(Dtor, Dtor_Complete));
3587ae0e2c9SDimitry Andric       else {
3597ae0e2c9SDimitry Andric         const CXXDestructorDecl *DDtor =
3607ae0e2c9SDimitry Andric           cast<CXXDestructorDecl>(DevirtualizedMethod);
36144290647SDimitry Andric         Callee = CGCallee::forDirect(
36244290647SDimitry Andric             CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty),
363*b5893f02SDimitry Andric             GlobalDecl(DDtor, Dtor_Complete));
3647ae0e2c9SDimitry Andric       }
36544290647SDimitry Andric       EmitCXXMemberOrOperatorCall(
36644290647SDimitry Andric           CalleeDecl, Callee, ReturnValue, This.getPointer(),
36744290647SDimitry Andric           /*ImplicitParam=*/nullptr, QualType(), CE, nullptr);
368f22ef01cSRoman Divacky     }
36959d1ed5bSDimitry Andric     return RValue::get(nullptr);
370f785676fSDimitry Andric   }
371f785676fSDimitry Andric 
37244290647SDimitry Andric   CGCallee Callee;
373f785676fSDimitry Andric   if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
37444290647SDimitry Andric     Callee = CGCallee::forDirect(
37544290647SDimitry Andric         CGM.GetAddrOfFunction(GlobalDecl(Ctor, Ctor_Complete), Ty),
376*b5893f02SDimitry Andric         GlobalDecl(Ctor, Ctor_Complete));
377e580952dSDimitry Andric   } else if (UseVirtualCall) {
3784ba319b5SDimitry Andric     Callee = CGCallee::forVirtual(CE, MD, This.getAddress(), Ty);
379f22ef01cSRoman Divacky   } else {
38033956c43SDimitry Andric     if (SanOpts.has(SanitizerKind::CFINVCall) &&
38133956c43SDimitry Andric         MD->getParent()->isDynamicClass()) {
3829a199699SDimitry Andric       llvm::Value *VTable;
3839a199699SDimitry Andric       const CXXRecordDecl *RD;
3849a199699SDimitry Andric       std::tie(VTable, RD) =
3854ba319b5SDimitry Andric           CGM.getCXXABI().LoadVTablePtr(*this, This.getAddress(),
3864ba319b5SDimitry Andric                                         MD->getParent());
387*b5893f02SDimitry Andric       EmitVTablePtrCheckForCall(RD, VTable, CFITCK_NVCall, CE->getBeginLoc());
38833956c43SDimitry Andric     }
38933956c43SDimitry Andric 
39039d628a0SDimitry Andric     if (getLangOpts().AppleKext && MD->isVirtual() && HasQualifier)
39139d628a0SDimitry Andric       Callee = BuildAppleKextVirtualCall(MD, Qualifier, Ty);
3927ae0e2c9SDimitry Andric     else if (!DevirtualizedMethod)
393*b5893f02SDimitry Andric       Callee =
394*b5893f02SDimitry Andric           CGCallee::forDirect(CGM.GetAddrOfFunction(MD, Ty), GlobalDecl(MD));
3957ae0e2c9SDimitry Andric     else {
396*b5893f02SDimitry Andric       Callee =
397*b5893f02SDimitry Andric           CGCallee::forDirect(CGM.GetAddrOfFunction(DevirtualizedMethod, Ty),
398*b5893f02SDimitry Andric                               GlobalDecl(DevirtualizedMethod));
3997ae0e2c9SDimitry Andric     }
400f22ef01cSRoman Divacky   }
401f22ef01cSRoman Divacky 
40259d1ed5bSDimitry Andric   if (MD->isVirtual()) {
4034ba319b5SDimitry Andric     Address NewThisAddr =
4044ba319b5SDimitry Andric         CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall(
4054ba319b5SDimitry Andric             *this, CalleeDecl, This.getAddress(), UseVirtualCall);
4064ba319b5SDimitry Andric     This.setAddress(NewThisAddr);
40759d1ed5bSDimitry Andric   }
408f785676fSDimitry Andric 
40944290647SDimitry Andric   return EmitCXXMemberOrOperatorCall(
41044290647SDimitry Andric       CalleeDecl, Callee, ReturnValue, This.getPointer(),
41144290647SDimitry Andric       /*ImplicitParam=*/nullptr, QualType(), CE, RtlArgs);
412f22ef01cSRoman Divacky }
413f22ef01cSRoman Divacky 
414f22ef01cSRoman Divacky RValue
EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr * E,ReturnValueSlot ReturnValue)415f22ef01cSRoman Divacky CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
416f22ef01cSRoman Divacky                                               ReturnValueSlot ReturnValue) {
417f22ef01cSRoman Divacky   const BinaryOperator *BO =
418f22ef01cSRoman Divacky       cast<BinaryOperator>(E->getCallee()->IgnoreParens());
419f22ef01cSRoman Divacky   const Expr *BaseExpr = BO->getLHS();
420f22ef01cSRoman Divacky   const Expr *MemFnExpr = BO->getRHS();
421f22ef01cSRoman Divacky 
422f22ef01cSRoman Divacky   const MemberPointerType *MPT =
4233b0f4066SDimitry Andric     MemFnExpr->getType()->castAs<MemberPointerType>();
424e580952dSDimitry Andric 
425f22ef01cSRoman Divacky   const FunctionProtoType *FPT =
4263b0f4066SDimitry Andric     MPT->getPointeeType()->castAs<FunctionProtoType>();
427f22ef01cSRoman Divacky   const CXXRecordDecl *RD =
428f22ef01cSRoman Divacky     cast<CXXRecordDecl>(MPT->getClass()->getAs<RecordType>()->getDecl());
429f22ef01cSRoman Divacky 
430f22ef01cSRoman Divacky   // Emit the 'this' pointer.
4310623d748SDimitry Andric   Address This = Address::invalid();
432e580952dSDimitry Andric   if (BO->getOpcode() == BO_PtrMemI)
4330623d748SDimitry Andric     This = EmitPointerWithAlignment(BaseExpr);
434f22ef01cSRoman Divacky   else
435f22ef01cSRoman Divacky     This = EmitLValue(BaseExpr).getAddress();
436f22ef01cSRoman Divacky 
4370623d748SDimitry Andric   EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.getPointer(),
4383861d79fSDimitry Andric                 QualType(MPT->getClass(), 0));
4393861d79fSDimitry Andric 
44044290647SDimitry Andric   // Get the member function pointer.
44144290647SDimitry Andric   llvm::Value *MemFnPtr = EmitScalarExpr(MemFnExpr);
44244290647SDimitry Andric 
443e580952dSDimitry Andric   // Ask the ABI to load the callee.  Note that This is modified.
4440623d748SDimitry Andric   llvm::Value *ThisPtrForCall = nullptr;
44544290647SDimitry Andric   CGCallee Callee =
4460623d748SDimitry Andric     CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(*this, BO, This,
4470623d748SDimitry Andric                                              ThisPtrForCall, MemFnPtr, MPT);
448f22ef01cSRoman Divacky 
449f22ef01cSRoman Divacky   CallArgList Args;
450f22ef01cSRoman Divacky 
451f22ef01cSRoman Divacky   QualType ThisType =
452f22ef01cSRoman Divacky     getContext().getPointerType(getContext().getTagDeclType(RD));
453f22ef01cSRoman Divacky 
454f22ef01cSRoman Divacky   // Push the this ptr.
4550623d748SDimitry Andric   Args.add(RValue::get(ThisPtrForCall), ThisType);
456f22ef01cSRoman Divacky 
457e7145dcbSDimitry Andric   RequiredArgs required =
458e7145dcbSDimitry Andric       RequiredArgs::forPrototypePlus(FPT, 1, /*FD=*/nullptr);
4597ae0e2c9SDimitry Andric 
460f22ef01cSRoman Divacky   // And the rest of the call args
461e7145dcbSDimitry Andric   EmitCallArgs(Args, FPT, E->arguments());
46220e90f04SDimitry Andric   return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required,
46320e90f04SDimitry Andric                                                       /*PrefixSize=*/0),
46413ddaa84SDimitry Andric                   Callee, ReturnValue, Args, nullptr, E->getExprLoc());
465f22ef01cSRoman Divacky }
466f22ef01cSRoman Divacky 
467f22ef01cSRoman Divacky RValue
EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr * E,const CXXMethodDecl * MD,ReturnValueSlot ReturnValue)468f22ef01cSRoman Divacky CodeGenFunction::EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
469f22ef01cSRoman Divacky                                                const CXXMethodDecl *MD,
470f22ef01cSRoman Divacky                                                ReturnValueSlot ReturnValue) {
471f22ef01cSRoman Divacky   assert(MD->isInstance() &&
472f22ef01cSRoman Divacky          "Trying to emit a member call expr on a static method!");
47339d628a0SDimitry Andric   return EmitCXXMemberOrOperatorMemberCallExpr(
47439d628a0SDimitry Andric       E, MD, ReturnValue, /*HasQualifier=*/false, /*Qualifier=*/nullptr,
47539d628a0SDimitry Andric       /*IsArrow=*/false, E->getArg(0));
476f22ef01cSRoman Divacky }
477f22ef01cSRoman Divacky 
EmitCUDAKernelCallExpr(const CUDAKernelCallExpr * E,ReturnValueSlot ReturnValue)4786122f3e6SDimitry Andric RValue CodeGenFunction::EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E,
4796122f3e6SDimitry Andric                                                ReturnValueSlot ReturnValue) {
4806122f3e6SDimitry Andric   return CGM.getCUDARuntime().EmitCUDAKernelCallExpr(*this, E, ReturnValue);
4816122f3e6SDimitry Andric }
4826122f3e6SDimitry Andric 
EmitNullBaseClassInitialization(CodeGenFunction & CGF,Address DestPtr,const CXXRecordDecl * Base)4836122f3e6SDimitry Andric static void EmitNullBaseClassInitialization(CodeGenFunction &CGF,
4840623d748SDimitry Andric                                             Address DestPtr,
4856122f3e6SDimitry Andric                                             const CXXRecordDecl *Base) {
4866122f3e6SDimitry Andric   if (Base->isEmpty())
4876122f3e6SDimitry Andric     return;
4886122f3e6SDimitry Andric 
4890623d748SDimitry Andric   DestPtr = CGF.Builder.CreateElementBitCast(DestPtr, CGF.Int8Ty);
4906122f3e6SDimitry Andric 
4916122f3e6SDimitry Andric   const ASTRecordLayout &Layout = CGF.getContext().getASTRecordLayout(Base);
4920623d748SDimitry Andric   CharUnits NVSize = Layout.getNonVirtualSize();
4936122f3e6SDimitry Andric 
4940623d748SDimitry Andric   // We cannot simply zero-initialize the entire base sub-object if vbptrs are
4950623d748SDimitry Andric   // present, they are initialized by the most derived class before calling the
4960623d748SDimitry Andric   // constructor.
4970623d748SDimitry Andric   SmallVector<std::pair<CharUnits, CharUnits>, 1> Stores;
4980623d748SDimitry Andric   Stores.emplace_back(CharUnits::Zero(), NVSize);
4990623d748SDimitry Andric 
5000623d748SDimitry Andric   // Each store is split by the existence of a vbptr.
5010623d748SDimitry Andric   CharUnits VBPtrWidth = CGF.getPointerSize();
5020623d748SDimitry Andric   std::vector<CharUnits> VBPtrOffsets =
5030623d748SDimitry Andric       CGF.CGM.getCXXABI().getVBPtrOffsets(Base);
5040623d748SDimitry Andric   for (CharUnits VBPtrOffset : VBPtrOffsets) {
505e7145dcbSDimitry Andric     // Stop before we hit any virtual base pointers located in virtual bases.
506e7145dcbSDimitry Andric     if (VBPtrOffset >= NVSize)
507e7145dcbSDimitry Andric       break;
5080623d748SDimitry Andric     std::pair<CharUnits, CharUnits> LastStore = Stores.pop_back_val();
5090623d748SDimitry Andric     CharUnits LastStoreOffset = LastStore.first;
5100623d748SDimitry Andric     CharUnits LastStoreSize = LastStore.second;
5110623d748SDimitry Andric 
5120623d748SDimitry Andric     CharUnits SplitBeforeOffset = LastStoreOffset;
5130623d748SDimitry Andric     CharUnits SplitBeforeSize = VBPtrOffset - SplitBeforeOffset;
5140623d748SDimitry Andric     assert(!SplitBeforeSize.isNegative() && "negative store size!");
5150623d748SDimitry Andric     if (!SplitBeforeSize.isZero())
5160623d748SDimitry Andric       Stores.emplace_back(SplitBeforeOffset, SplitBeforeSize);
5170623d748SDimitry Andric 
5180623d748SDimitry Andric     CharUnits SplitAfterOffset = VBPtrOffset + VBPtrWidth;
5190623d748SDimitry Andric     CharUnits SplitAfterSize = LastStoreSize - SplitAfterOffset;
5200623d748SDimitry Andric     assert(!SplitAfterSize.isNegative() && "negative store size!");
5210623d748SDimitry Andric     if (!SplitAfterSize.isZero())
5220623d748SDimitry Andric       Stores.emplace_back(SplitAfterOffset, SplitAfterSize);
5230623d748SDimitry Andric   }
5246122f3e6SDimitry Andric 
5256122f3e6SDimitry Andric   // If the type contains a pointer to data member we can't memset it to zero.
5266122f3e6SDimitry Andric   // Instead, create a null constant and copy it to the destination.
5276122f3e6SDimitry Andric   // TODO: there are other patterns besides zero that we can usefully memset,
5286122f3e6SDimitry Andric   // like -1, which happens to be the pattern used by member-pointers.
5296122f3e6SDimitry Andric   // TODO: isZeroInitializable can be over-conservative in the case where a
5306122f3e6SDimitry Andric   // virtual base contains a member pointer.
5310623d748SDimitry Andric   llvm::Constant *NullConstantForBase = CGF.CGM.EmitNullConstantForBase(Base);
5320623d748SDimitry Andric   if (!NullConstantForBase->isNullValue()) {
5330623d748SDimitry Andric     llvm::GlobalVariable *NullVariable = new llvm::GlobalVariable(
5340623d748SDimitry Andric         CGF.CGM.getModule(), NullConstantForBase->getType(),
5350623d748SDimitry Andric         /*isConstant=*/true, llvm::GlobalVariable::PrivateLinkage,
5360623d748SDimitry Andric         NullConstantForBase, Twine());
5376122f3e6SDimitry Andric 
5380623d748SDimitry Andric     CharUnits Align = std::max(Layout.getNonVirtualAlignment(),
5390623d748SDimitry Andric                                DestPtr.getAlignment());
5406122f3e6SDimitry Andric     NullVariable->setAlignment(Align.getQuantity());
5410623d748SDimitry Andric 
5420623d748SDimitry Andric     Address SrcPtr = Address(CGF.EmitCastToVoidPtr(NullVariable), Align);
5436122f3e6SDimitry Andric 
5446122f3e6SDimitry Andric     // Get and call the appropriate llvm.memcpy overload.
5450623d748SDimitry Andric     for (std::pair<CharUnits, CharUnits> Store : Stores) {
5460623d748SDimitry Andric       CharUnits StoreOffset = Store.first;
5470623d748SDimitry Andric       CharUnits StoreSize = Store.second;
5480623d748SDimitry Andric       llvm::Value *StoreSizeVal = CGF.CGM.getSize(StoreSize);
5490623d748SDimitry Andric       CGF.Builder.CreateMemCpy(
5500623d748SDimitry Andric           CGF.Builder.CreateConstInBoundsByteGEP(DestPtr, StoreOffset),
5510623d748SDimitry Andric           CGF.Builder.CreateConstInBoundsByteGEP(SrcPtr, StoreOffset),
5520623d748SDimitry Andric           StoreSizeVal);
5536122f3e6SDimitry Andric     }
5546122f3e6SDimitry Andric 
5556122f3e6SDimitry Andric   // Otherwise, just memset the whole thing to zero.  This is legal
5566122f3e6SDimitry Andric   // because in LLVM, all default initializers (other than the ones we just
5576122f3e6SDimitry Andric   // handled above) are guaranteed to have a bit pattern of all zeros.
5580623d748SDimitry Andric   } else {
5590623d748SDimitry Andric     for (std::pair<CharUnits, CharUnits> Store : Stores) {
5600623d748SDimitry Andric       CharUnits StoreOffset = Store.first;
5610623d748SDimitry Andric       CharUnits StoreSize = Store.second;
5620623d748SDimitry Andric       llvm::Value *StoreSizeVal = CGF.CGM.getSize(StoreSize);
5630623d748SDimitry Andric       CGF.Builder.CreateMemSet(
5640623d748SDimitry Andric           CGF.Builder.CreateConstInBoundsByteGEP(DestPtr, StoreOffset),
5650623d748SDimitry Andric           CGF.Builder.getInt8(0), StoreSizeVal);
5660623d748SDimitry Andric     }
5670623d748SDimitry Andric   }
5686122f3e6SDimitry Andric }
5696122f3e6SDimitry Andric 
570f22ef01cSRoman Divacky void
EmitCXXConstructExpr(const CXXConstructExpr * E,AggValueSlot Dest)5712754fe60SDimitry Andric CodeGenFunction::EmitCXXConstructExpr(const CXXConstructExpr *E,
5722754fe60SDimitry Andric                                       AggValueSlot Dest) {
5732754fe60SDimitry Andric   assert(!Dest.isIgnored() && "Must have a destination!");
574f22ef01cSRoman Divacky   const CXXConstructorDecl *CD = E->getConstructor();
575e580952dSDimitry Andric 
576e580952dSDimitry Andric   // If we require zero initialization before (or instead of) calling the
577e580952dSDimitry Andric   // constructor, as can be the case with a non-user-provided default
5783b0f4066SDimitry Andric   // constructor, emit the zero initialization now, unless destination is
5793b0f4066SDimitry Andric   // already zeroed.
5806122f3e6SDimitry Andric   if (E->requiresZeroInitialization() && !Dest.isZeroed()) {
5816122f3e6SDimitry Andric     switch (E->getConstructionKind()) {
5826122f3e6SDimitry Andric     case CXXConstructExpr::CK_Delegating:
5836122f3e6SDimitry Andric     case CXXConstructExpr::CK_Complete:
5840623d748SDimitry Andric       EmitNullInitialization(Dest.getAddress(), E->getType());
5856122f3e6SDimitry Andric       break;
5866122f3e6SDimitry Andric     case CXXConstructExpr::CK_VirtualBase:
5876122f3e6SDimitry Andric     case CXXConstructExpr::CK_NonVirtualBase:
5880623d748SDimitry Andric       EmitNullBaseClassInitialization(*this, Dest.getAddress(),
5890623d748SDimitry Andric                                       CD->getParent());
5906122f3e6SDimitry Andric       break;
5916122f3e6SDimitry Andric     }
5926122f3e6SDimitry Andric   }
593e580952dSDimitry Andric 
594e580952dSDimitry Andric   // If this is a call to a trivial default constructor, do nothing.
595e580952dSDimitry Andric   if (CD->isTrivial() && CD->isDefaultConstructor())
596f22ef01cSRoman Divacky     return;
597e580952dSDimitry Andric 
5982754fe60SDimitry Andric   // Elide the constructor if we're constructing from a temporary.
5992754fe60SDimitry Andric   // The temporary check is required because Sema sets this on NRVO
6002754fe60SDimitry Andric   // returns.
6013861d79fSDimitry Andric   if (getLangOpts().ElideConstructors && E->isElidable()) {
6022754fe60SDimitry Andric     assert(getContext().hasSameUnqualifiedType(E->getType(),
6032754fe60SDimitry Andric                                                E->getArg(0)->getType()));
6042754fe60SDimitry Andric     if (E->getArg(0)->isTemporaryObject(getContext(), CD->getParent())) {
6052754fe60SDimitry Andric       EmitAggExpr(E->getArg(0), Dest);
606f22ef01cSRoman Divacky       return;
607f22ef01cSRoman Divacky     }
608f22ef01cSRoman Divacky   }
609e580952dSDimitry Andric 
610e7145dcbSDimitry Andric   if (const ArrayType *arrayType
611e7145dcbSDimitry Andric         = getContext().getAsArrayType(E->getType())) {
6124ba319b5SDimitry Andric     EmitCXXAggrConstructorCall(CD, arrayType, Dest.getAddress(), E,
6134ba319b5SDimitry Andric                                Dest.isSanitizerChecked());
61417a519f9SDimitry Andric   } else {
615bd5abe19SDimitry Andric     CXXCtorType Type = Ctor_Complete;
616bd5abe19SDimitry Andric     bool ForVirtualBase = false;
617139f7f9bSDimitry Andric     bool Delegating = false;
618bd5abe19SDimitry Andric 
619bd5abe19SDimitry Andric     switch (E->getConstructionKind()) {
620bd5abe19SDimitry Andric      case CXXConstructExpr::CK_Delegating:
6213b0f4066SDimitry Andric       // We should be emitting a constructor; GlobalDecl will assert this
6223b0f4066SDimitry Andric       Type = CurGD.getCtorType();
623139f7f9bSDimitry Andric       Delegating = true;
624bd5abe19SDimitry Andric       break;
6253b0f4066SDimitry Andric 
626bd5abe19SDimitry Andric      case CXXConstructExpr::CK_Complete:
627bd5abe19SDimitry Andric       Type = Ctor_Complete;
628bd5abe19SDimitry Andric       break;
629bd5abe19SDimitry Andric 
630bd5abe19SDimitry Andric      case CXXConstructExpr::CK_VirtualBase:
631bd5abe19SDimitry Andric       ForVirtualBase = true;
63213ddaa84SDimitry Andric       LLVM_FALLTHROUGH;
633bd5abe19SDimitry Andric 
634bd5abe19SDimitry Andric      case CXXConstructExpr::CK_NonVirtualBase:
635bd5abe19SDimitry Andric       Type = Ctor_Base;
636bd5abe19SDimitry Andric     }
637f22ef01cSRoman Divacky 
638f22ef01cSRoman Divacky     // Call the constructor.
6390623d748SDimitry Andric     EmitCXXConstructorCall(CD, Type, ForVirtualBase, Delegating,
6404ba319b5SDimitry Andric                            Dest.getAddress(), E, Dest.mayOverlap(),
6414ba319b5SDimitry Andric                            Dest.isSanitizerChecked());
642f22ef01cSRoman Divacky   }
643f22ef01cSRoman Divacky }
644f22ef01cSRoman Divacky 
EmitSynthesizedCXXCopyCtor(Address Dest,Address Src,const Expr * Exp)6450623d748SDimitry Andric void CodeGenFunction::EmitSynthesizedCXXCopyCtor(Address Dest, Address Src,
6462754fe60SDimitry Andric                                                  const Expr *Exp) {
6472754fe60SDimitry Andric   if (const ExprWithCleanups *E = dyn_cast<ExprWithCleanups>(Exp))
6482754fe60SDimitry Andric     Exp = E->getSubExpr();
6492754fe60SDimitry Andric   assert(isa<CXXConstructExpr>(Exp) &&
6502754fe60SDimitry Andric          "EmitSynthesizedCXXCopyCtor - unknown copy ctor expr");
6512754fe60SDimitry Andric   const CXXConstructExpr* E = cast<CXXConstructExpr>(Exp);
6522754fe60SDimitry Andric   const CXXConstructorDecl *CD = E->getConstructor();
6532754fe60SDimitry Andric   RunCleanupsScope Scope(*this);
6542754fe60SDimitry Andric 
6552754fe60SDimitry Andric   // If we require zero initialization before (or instead of) calling the
6562754fe60SDimitry Andric   // constructor, as can be the case with a non-user-provided default
6572754fe60SDimitry Andric   // constructor, emit the zero initialization now.
6582754fe60SDimitry Andric   // FIXME. Do I still need this for a copy ctor synthesis?
6592754fe60SDimitry Andric   if (E->requiresZeroInitialization())
6602754fe60SDimitry Andric     EmitNullInitialization(Dest, E->getType());
6612754fe60SDimitry Andric 
6622754fe60SDimitry Andric   assert(!getContext().getAsConstantArrayType(E->getType())
6632754fe60SDimitry Andric          && "EmitSynthesizedCXXCopyCtor - Copied-in Array");
66439d628a0SDimitry Andric   EmitSynthesizedCXXCopyCtorCall(CD, Dest, Src, E);
6652754fe60SDimitry Andric }
6662754fe60SDimitry Andric 
CalculateCookiePadding(CodeGenFunction & CGF,const CXXNewExpr * E)667e580952dSDimitry Andric static CharUnits CalculateCookiePadding(CodeGenFunction &CGF,
668e580952dSDimitry Andric                                         const CXXNewExpr *E) {
669f22ef01cSRoman Divacky   if (!E->isArray())
670f22ef01cSRoman Divacky     return CharUnits::Zero();
671f22ef01cSRoman Divacky 
672bd5abe19SDimitry Andric   // No cookie is required if the operator new[] being used is the
673bd5abe19SDimitry Andric   // reserved placement operator new[].
674bd5abe19SDimitry Andric   if (E->getOperatorNew()->isReservedGlobalPlacementOperator())
675f22ef01cSRoman Divacky     return CharUnits::Zero();
676f22ef01cSRoman Divacky 
6772754fe60SDimitry Andric   return CGF.CGM.getCXXABI().GetArrayCookieSize(E);
678f22ef01cSRoman Divacky }
679f22ef01cSRoman Divacky 
EmitCXXNewAllocSize(CodeGenFunction & CGF,const CXXNewExpr * e,unsigned minElements,llvm::Value * & numElements,llvm::Value * & sizeWithoutCookie)680bd5abe19SDimitry Andric static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF,
681bd5abe19SDimitry Andric                                         const CXXNewExpr *e,
682dff0c46cSDimitry Andric                                         unsigned minElements,
683bd5abe19SDimitry Andric                                         llvm::Value *&numElements,
684bd5abe19SDimitry Andric                                         llvm::Value *&sizeWithoutCookie) {
685bd5abe19SDimitry Andric   QualType type = e->getAllocatedType();
686f22ef01cSRoman Divacky 
687bd5abe19SDimitry Andric   if (!e->isArray()) {
688bd5abe19SDimitry Andric     CharUnits typeSize = CGF.getContext().getTypeSizeInChars(type);
689bd5abe19SDimitry Andric     sizeWithoutCookie
690bd5abe19SDimitry Andric       = llvm::ConstantInt::get(CGF.SizeTy, typeSize.getQuantity());
691bd5abe19SDimitry Andric     return sizeWithoutCookie;
692f22ef01cSRoman Divacky   }
693f22ef01cSRoman Divacky 
694bd5abe19SDimitry Andric   // The width of size_t.
695bd5abe19SDimitry Andric   unsigned sizeWidth = CGF.SizeTy->getBitWidth();
696bd5abe19SDimitry Andric 
697e580952dSDimitry Andric   // Figure out the cookie size.
698bd5abe19SDimitry Andric   llvm::APInt cookieSize(sizeWidth,
699bd5abe19SDimitry Andric                          CalculateCookiePadding(CGF, e).getQuantity());
700f22ef01cSRoman Divacky 
701f22ef01cSRoman Divacky   // Emit the array size expression.
702e580952dSDimitry Andric   // We multiply the size of all dimensions for NumElements.
703e580952dSDimitry Andric   // e.g for 'int[2][3]', ElemType is 'int' and NumElements is 6.
7049a199699SDimitry Andric   numElements =
7059a199699SDimitry Andric     ConstantEmitter(CGF).tryEmitAbstract(e->getArraySize(), e->getType());
70620e90f04SDimitry Andric   if (!numElements)
707bd5abe19SDimitry Andric     numElements = CGF.EmitScalarExpr(e->getArraySize());
708bd5abe19SDimitry Andric   assert(isa<llvm::IntegerType>(numElements->getType()));
709f22ef01cSRoman Divacky 
710bd5abe19SDimitry Andric   // The number of elements can be have an arbitrary integer type;
711bd5abe19SDimitry Andric   // essentially, we need to multiply it by a constant factor, add a
712bd5abe19SDimitry Andric   // cookie size, and verify that the result is representable as a
713bd5abe19SDimitry Andric   // size_t.  That's just a gloss, though, and it's wrong in one
714bd5abe19SDimitry Andric   // important way: if the count is negative, it's an error even if
715bd5abe19SDimitry Andric   // the cookie size would bring the total size >= 0.
716bd5abe19SDimitry Andric   bool isSigned
717bd5abe19SDimitry Andric     = e->getArraySize()->getType()->isSignedIntegerOrEnumerationType();
7186122f3e6SDimitry Andric   llvm::IntegerType *numElementsType
719bd5abe19SDimitry Andric     = cast<llvm::IntegerType>(numElements->getType());
720bd5abe19SDimitry Andric   unsigned numElementsWidth = numElementsType->getBitWidth();
721bd5abe19SDimitry Andric 
722bd5abe19SDimitry Andric   // Compute the constant factor.
723bd5abe19SDimitry Andric   llvm::APInt arraySizeMultiplier(sizeWidth, 1);
724e580952dSDimitry Andric   while (const ConstantArrayType *CAT
725bd5abe19SDimitry Andric              = CGF.getContext().getAsConstantArrayType(type)) {
726bd5abe19SDimitry Andric     type = CAT->getElementType();
727bd5abe19SDimitry Andric     arraySizeMultiplier *= CAT->getSize();
728f22ef01cSRoman Divacky   }
729f22ef01cSRoman Divacky 
730bd5abe19SDimitry Andric   CharUnits typeSize = CGF.getContext().getTypeSizeInChars(type);
731bd5abe19SDimitry Andric   llvm::APInt typeSizeMultiplier(sizeWidth, typeSize.getQuantity());
732bd5abe19SDimitry Andric   typeSizeMultiplier *= arraySizeMultiplier;
733bd5abe19SDimitry Andric 
734bd5abe19SDimitry Andric   // This will be a size_t.
735bd5abe19SDimitry Andric   llvm::Value *size;
736f22ef01cSRoman Divacky 
737e580952dSDimitry Andric   // If someone is doing 'new int[42]' there is no need to do a dynamic check.
738e580952dSDimitry Andric   // Don't bloat the -O0 code.
739bd5abe19SDimitry Andric   if (llvm::ConstantInt *numElementsC =
740bd5abe19SDimitry Andric         dyn_cast<llvm::ConstantInt>(numElements)) {
741bd5abe19SDimitry Andric     const llvm::APInt &count = numElementsC->getValue();
742e580952dSDimitry Andric 
743bd5abe19SDimitry Andric     bool hasAnyOverflow = false;
744e580952dSDimitry Andric 
745bd5abe19SDimitry Andric     // If 'count' was a negative number, it's an overflow.
746bd5abe19SDimitry Andric     if (isSigned && count.isNegative())
747bd5abe19SDimitry Andric       hasAnyOverflow = true;
748e580952dSDimitry Andric 
749bd5abe19SDimitry Andric     // We want to do all this arithmetic in size_t.  If numElements is
750bd5abe19SDimitry Andric     // wider than that, check whether it's already too big, and if so,
751bd5abe19SDimitry Andric     // overflow.
752bd5abe19SDimitry Andric     else if (numElementsWidth > sizeWidth &&
753bd5abe19SDimitry Andric              numElementsWidth - sizeWidth > count.countLeadingZeros())
754bd5abe19SDimitry Andric       hasAnyOverflow = true;
755bd5abe19SDimitry Andric 
756bd5abe19SDimitry Andric     // Okay, compute a count at the right width.
757bd5abe19SDimitry Andric     llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
758bd5abe19SDimitry Andric 
759dff0c46cSDimitry Andric     // If there is a brace-initializer, we cannot allocate fewer elements than
760dff0c46cSDimitry Andric     // there are initializers. If we do, that's treated like an overflow.
761dff0c46cSDimitry Andric     if (adjustedCount.ult(minElements))
762dff0c46cSDimitry Andric       hasAnyOverflow = true;
763dff0c46cSDimitry Andric 
764bd5abe19SDimitry Andric     // Scale numElements by that.  This might overflow, but we don't
765bd5abe19SDimitry Andric     // care because it only overflows if allocationSize does, too, and
766bd5abe19SDimitry Andric     // if that overflows then we shouldn't use this.
767bd5abe19SDimitry Andric     numElements = llvm::ConstantInt::get(CGF.SizeTy,
768bd5abe19SDimitry Andric                                          adjustedCount * arraySizeMultiplier);
769bd5abe19SDimitry Andric 
770bd5abe19SDimitry Andric     // Compute the size before cookie, and track whether it overflowed.
771bd5abe19SDimitry Andric     bool overflow;
772bd5abe19SDimitry Andric     llvm::APInt allocationSize
773bd5abe19SDimitry Andric       = adjustedCount.umul_ov(typeSizeMultiplier, overflow);
774bd5abe19SDimitry Andric     hasAnyOverflow |= overflow;
775bd5abe19SDimitry Andric 
776bd5abe19SDimitry Andric     // Add in the cookie, and check whether it's overflowed.
777bd5abe19SDimitry Andric     if (cookieSize != 0) {
778bd5abe19SDimitry Andric       // Save the current size without a cookie.  This shouldn't be
779bd5abe19SDimitry Andric       // used if there was overflow.
780bd5abe19SDimitry Andric       sizeWithoutCookie = llvm::ConstantInt::get(CGF.SizeTy, allocationSize);
781bd5abe19SDimitry Andric 
782bd5abe19SDimitry Andric       allocationSize = allocationSize.uadd_ov(cookieSize, overflow);
783bd5abe19SDimitry Andric       hasAnyOverflow |= overflow;
784e580952dSDimitry Andric     }
785e580952dSDimitry Andric 
786bd5abe19SDimitry Andric     // On overflow, produce a -1 so operator new will fail.
787bd5abe19SDimitry Andric     if (hasAnyOverflow) {
788bd5abe19SDimitry Andric       size = llvm::Constant::getAllOnesValue(CGF.SizeTy);
789e580952dSDimitry Andric     } else {
790bd5abe19SDimitry Andric       size = llvm::ConstantInt::get(CGF.SizeTy, allocationSize);
791e580952dSDimitry Andric     }
792e580952dSDimitry Andric 
793bd5abe19SDimitry Andric   // Otherwise, we might need to use the overflow intrinsics.
794e580952dSDimitry Andric   } else {
795dff0c46cSDimitry Andric     // There are up to five conditions we need to test for:
796bd5abe19SDimitry Andric     // 1) if isSigned, we need to check whether numElements is negative;
797bd5abe19SDimitry Andric     // 2) if numElementsWidth > sizeWidth, we need to check whether
798bd5abe19SDimitry Andric     //   numElements is larger than something representable in size_t;
799dff0c46cSDimitry Andric     // 3) if minElements > 0, we need to check whether numElements is smaller
800dff0c46cSDimitry Andric     //    than that.
801dff0c46cSDimitry Andric     // 4) we need to compute
802bd5abe19SDimitry Andric     //      sizeWithoutCookie := numElements * typeSizeMultiplier
803bd5abe19SDimitry Andric     //    and check whether it overflows; and
804dff0c46cSDimitry Andric     // 5) if we need a cookie, we need to compute
805bd5abe19SDimitry Andric     //      size := sizeWithoutCookie + cookieSize
806bd5abe19SDimitry Andric     //    and check whether it overflows.
807e580952dSDimitry Andric 
80859d1ed5bSDimitry Andric     llvm::Value *hasOverflow = nullptr;
809e580952dSDimitry Andric 
810bd5abe19SDimitry Andric     // If numElementsWidth > sizeWidth, then one way or another, we're
811bd5abe19SDimitry Andric     // going to have to do a comparison for (2), and this happens to
812bd5abe19SDimitry Andric     // take care of (1), too.
813bd5abe19SDimitry Andric     if (numElementsWidth > sizeWidth) {
814bd5abe19SDimitry Andric       llvm::APInt threshold(numElementsWidth, 1);
815bd5abe19SDimitry Andric       threshold <<= sizeWidth;
816e580952dSDimitry Andric 
817bd5abe19SDimitry Andric       llvm::Value *thresholdV
818bd5abe19SDimitry Andric         = llvm::ConstantInt::get(numElementsType, threshold);
819bd5abe19SDimitry Andric 
820bd5abe19SDimitry Andric       hasOverflow = CGF.Builder.CreateICmpUGE(numElements, thresholdV);
821bd5abe19SDimitry Andric       numElements = CGF.Builder.CreateTrunc(numElements, CGF.SizeTy);
822bd5abe19SDimitry Andric 
823bd5abe19SDimitry Andric     // Otherwise, if we're signed, we want to sext up to size_t.
824bd5abe19SDimitry Andric     } else if (isSigned) {
825bd5abe19SDimitry Andric       if (numElementsWidth < sizeWidth)
826bd5abe19SDimitry Andric         numElements = CGF.Builder.CreateSExt(numElements, CGF.SizeTy);
827bd5abe19SDimitry Andric 
828bd5abe19SDimitry Andric       // If there's a non-1 type size multiplier, then we can do the
829bd5abe19SDimitry Andric       // signedness check at the same time as we do the multiply
830bd5abe19SDimitry Andric       // because a negative number times anything will cause an
831dff0c46cSDimitry Andric       // unsigned overflow.  Otherwise, we have to do it here. But at least
832dff0c46cSDimitry Andric       // in this case, we can subsume the >= minElements check.
833bd5abe19SDimitry Andric       if (typeSizeMultiplier == 1)
834bd5abe19SDimitry Andric         hasOverflow = CGF.Builder.CreateICmpSLT(numElements,
835dff0c46cSDimitry Andric                               llvm::ConstantInt::get(CGF.SizeTy, minElements));
836bd5abe19SDimitry Andric 
837bd5abe19SDimitry Andric     // Otherwise, zext up to size_t if necessary.
838bd5abe19SDimitry Andric     } else if (numElementsWidth < sizeWidth) {
839bd5abe19SDimitry Andric       numElements = CGF.Builder.CreateZExt(numElements, CGF.SizeTy);
840bd5abe19SDimitry Andric     }
841bd5abe19SDimitry Andric 
842bd5abe19SDimitry Andric     assert(numElements->getType() == CGF.SizeTy);
843bd5abe19SDimitry Andric 
844dff0c46cSDimitry Andric     if (minElements) {
845dff0c46cSDimitry Andric       // Don't allow allocation of fewer elements than we have initializers.
846dff0c46cSDimitry Andric       if (!hasOverflow) {
847dff0c46cSDimitry Andric         hasOverflow = CGF.Builder.CreateICmpULT(numElements,
848dff0c46cSDimitry Andric                               llvm::ConstantInt::get(CGF.SizeTy, minElements));
849dff0c46cSDimitry Andric       } else if (numElementsWidth > sizeWidth) {
850dff0c46cSDimitry Andric         // The other existing overflow subsumes this check.
851dff0c46cSDimitry Andric         // We do an unsigned comparison, since any signed value < -1 is
852dff0c46cSDimitry Andric         // taken care of either above or below.
853dff0c46cSDimitry Andric         hasOverflow = CGF.Builder.CreateOr(hasOverflow,
854dff0c46cSDimitry Andric                           CGF.Builder.CreateICmpULT(numElements,
855dff0c46cSDimitry Andric                               llvm::ConstantInt::get(CGF.SizeTy, minElements)));
856dff0c46cSDimitry Andric       }
857dff0c46cSDimitry Andric     }
858dff0c46cSDimitry Andric 
859bd5abe19SDimitry Andric     size = numElements;
860bd5abe19SDimitry Andric 
861bd5abe19SDimitry Andric     // Multiply by the type size if necessary.  This multiplier
862bd5abe19SDimitry Andric     // includes all the factors for nested arrays.
863e580952dSDimitry Andric     //
864bd5abe19SDimitry Andric     // This step also causes numElements to be scaled up by the
865bd5abe19SDimitry Andric     // nested-array factor if necessary.  Overflow on this computation
866bd5abe19SDimitry Andric     // can be ignored because the result shouldn't be used if
867bd5abe19SDimitry Andric     // allocation fails.
868bd5abe19SDimitry Andric     if (typeSizeMultiplier != 1) {
869bd5abe19SDimitry Andric       llvm::Value *umul_with_overflow
87017a519f9SDimitry Andric         = CGF.CGM.getIntrinsic(llvm::Intrinsic::umul_with_overflow, CGF.SizeTy);
871e580952dSDimitry Andric 
872bd5abe19SDimitry Andric       llvm::Value *tsmV =
873bd5abe19SDimitry Andric         llvm::ConstantInt::get(CGF.SizeTy, typeSizeMultiplier);
874bd5abe19SDimitry Andric       llvm::Value *result =
87533956c43SDimitry Andric           CGF.Builder.CreateCall(umul_with_overflow, {size, tsmV});
876e580952dSDimitry Andric 
877bd5abe19SDimitry Andric       llvm::Value *overflowed = CGF.Builder.CreateExtractValue(result, 1);
878bd5abe19SDimitry Andric       if (hasOverflow)
879bd5abe19SDimitry Andric         hasOverflow = CGF.Builder.CreateOr(hasOverflow, overflowed);
880e580952dSDimitry Andric       else
881bd5abe19SDimitry Andric         hasOverflow = overflowed;
882e580952dSDimitry Andric 
883bd5abe19SDimitry Andric       size = CGF.Builder.CreateExtractValue(result, 0);
884bd5abe19SDimitry Andric 
885bd5abe19SDimitry Andric       // Also scale up numElements by the array size multiplier.
886bd5abe19SDimitry Andric       if (arraySizeMultiplier != 1) {
887bd5abe19SDimitry Andric         // If the base element type size is 1, then we can re-use the
888bd5abe19SDimitry Andric         // multiply we just did.
889bd5abe19SDimitry Andric         if (typeSize.isOne()) {
890bd5abe19SDimitry Andric           assert(arraySizeMultiplier == typeSizeMultiplier);
891bd5abe19SDimitry Andric           numElements = size;
892bd5abe19SDimitry Andric 
893bd5abe19SDimitry Andric         // Otherwise we need a separate multiply.
894bd5abe19SDimitry Andric         } else {
895bd5abe19SDimitry Andric           llvm::Value *asmV =
896bd5abe19SDimitry Andric             llvm::ConstantInt::get(CGF.SizeTy, arraySizeMultiplier);
897bd5abe19SDimitry Andric           numElements = CGF.Builder.CreateMul(numElements, asmV);
898bd5abe19SDimitry Andric         }
899bd5abe19SDimitry Andric       }
900bd5abe19SDimitry Andric     } else {
901bd5abe19SDimitry Andric       // numElements doesn't need to be scaled.
902bd5abe19SDimitry Andric       assert(arraySizeMultiplier == 1);
903bd5abe19SDimitry Andric     }
904bd5abe19SDimitry Andric 
905bd5abe19SDimitry Andric     // Add in the cookie size if necessary.
906bd5abe19SDimitry Andric     if (cookieSize != 0) {
907bd5abe19SDimitry Andric       sizeWithoutCookie = size;
908bd5abe19SDimitry Andric 
909bd5abe19SDimitry Andric       llvm::Value *uadd_with_overflow
91017a519f9SDimitry Andric         = CGF.CGM.getIntrinsic(llvm::Intrinsic::uadd_with_overflow, CGF.SizeTy);
911bd5abe19SDimitry Andric 
912bd5abe19SDimitry Andric       llvm::Value *cookieSizeV = llvm::ConstantInt::get(CGF.SizeTy, cookieSize);
913bd5abe19SDimitry Andric       llvm::Value *result =
91433956c43SDimitry Andric           CGF.Builder.CreateCall(uadd_with_overflow, {size, cookieSizeV});
915bd5abe19SDimitry Andric 
916bd5abe19SDimitry Andric       llvm::Value *overflowed = CGF.Builder.CreateExtractValue(result, 1);
917bd5abe19SDimitry Andric       if (hasOverflow)
918bd5abe19SDimitry Andric         hasOverflow = CGF.Builder.CreateOr(hasOverflow, overflowed);
919bd5abe19SDimitry Andric       else
920bd5abe19SDimitry Andric         hasOverflow = overflowed;
921bd5abe19SDimitry Andric 
922bd5abe19SDimitry Andric       size = CGF.Builder.CreateExtractValue(result, 0);
923bd5abe19SDimitry Andric     }
924bd5abe19SDimitry Andric 
925bd5abe19SDimitry Andric     // If we had any possibility of dynamic overflow, make a select to
926bd5abe19SDimitry Andric     // overwrite 'size' with an all-ones value, which should cause
927bd5abe19SDimitry Andric     // operator new to throw.
928bd5abe19SDimitry Andric     if (hasOverflow)
929bd5abe19SDimitry Andric       size = CGF.Builder.CreateSelect(hasOverflow,
930bd5abe19SDimitry Andric                                  llvm::Constant::getAllOnesValue(CGF.SizeTy),
931bd5abe19SDimitry Andric                                       size);
932bd5abe19SDimitry Andric   }
933bd5abe19SDimitry Andric 
934bd5abe19SDimitry Andric   if (cookieSize == 0)
935bd5abe19SDimitry Andric     sizeWithoutCookie = size;
936bd5abe19SDimitry Andric   else
937bd5abe19SDimitry Andric     assert(sizeWithoutCookie && "didn't set sizeWithoutCookie?");
938bd5abe19SDimitry Andric 
939bd5abe19SDimitry Andric   return size;
940f22ef01cSRoman Divacky }
941f22ef01cSRoman Divacky 
StoreAnyExprIntoOneUnit(CodeGenFunction & CGF,const Expr * Init,QualType AllocType,Address NewPtr,AggValueSlot::Overlap_t MayOverlap)942dff0c46cSDimitry Andric static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init,
9434ba319b5SDimitry Andric                                     QualType AllocType, Address NewPtr,
9444ba319b5SDimitry Andric                                     AggValueSlot::Overlap_t MayOverlap) {
945f785676fSDimitry Andric   // FIXME: Refactor with EmitExprAsInit.
946139f7f9bSDimitry Andric   switch (CGF.getEvaluationKind(AllocType)) {
947139f7f9bSDimitry Andric   case TEK_Scalar:
94839d628a0SDimitry Andric     CGF.EmitScalarInit(Init, nullptr,
9490623d748SDimitry Andric                        CGF.MakeAddrLValue(NewPtr, AllocType), false);
950139f7f9bSDimitry Andric     return;
951139f7f9bSDimitry Andric   case TEK_Complex:
9520623d748SDimitry Andric     CGF.EmitComplexExprIntoLValue(Init, CGF.MakeAddrLValue(NewPtr, AllocType),
953139f7f9bSDimitry Andric                                   /*isInit*/ true);
954139f7f9bSDimitry Andric     return;
955139f7f9bSDimitry Andric   case TEK_Aggregate: {
9562754fe60SDimitry Andric     AggValueSlot Slot
9570623d748SDimitry Andric       = AggValueSlot::forAddr(NewPtr, AllocType.getQualifiers(),
9586122f3e6SDimitry Andric                               AggValueSlot::IsDestructed,
9596122f3e6SDimitry Andric                               AggValueSlot::DoesNotNeedGCBarriers,
9604ba319b5SDimitry Andric                               AggValueSlot::IsNotAliased,
9614ba319b5SDimitry Andric                               MayOverlap, AggValueSlot::IsNotZeroed,
9624ba319b5SDimitry Andric                               AggValueSlot::IsSanitizerChecked);
9632754fe60SDimitry Andric     CGF.EmitAggExpr(Init, Slot);
964139f7f9bSDimitry Andric     return;
9652754fe60SDimitry Andric   }
966ffd1746dSEd Schouten   }
967139f7f9bSDimitry Andric   llvm_unreachable("bad evaluation kind");
968139f7f9bSDimitry Andric }
969ffd1746dSEd Schouten 
EmitNewArrayInitializer(const CXXNewExpr * E,QualType ElementType,llvm::Type * ElementTy,Address BeginPtr,llvm::Value * NumElements,llvm::Value * AllocSizeWithoutCookie)97033956c43SDimitry Andric void CodeGenFunction::EmitNewArrayInitializer(
97133956c43SDimitry Andric     const CXXNewExpr *E, QualType ElementType, llvm::Type *ElementTy,
9720623d748SDimitry Andric     Address BeginPtr, llvm::Value *NumElements,
97359d1ed5bSDimitry Andric     llvm::Value *AllocSizeWithoutCookie) {
97459d1ed5bSDimitry Andric   // If we have a type with trivial initialization and no initializer,
97559d1ed5bSDimitry Andric   // there's nothing to do.
976dff0c46cSDimitry Andric   if (!E->hasInitializer())
97759d1ed5bSDimitry Andric     return;
978ffd1746dSEd Schouten 
9790623d748SDimitry Andric   Address CurPtr = BeginPtr;
980ffd1746dSEd Schouten 
98159d1ed5bSDimitry Andric   unsigned InitListElements = 0;
982dff0c46cSDimitry Andric 
983dff0c46cSDimitry Andric   const Expr *Init = E->getInitializer();
9840623d748SDimitry Andric   Address EndOfInit = Address::invalid();
98559d1ed5bSDimitry Andric   QualType::DestructionKind DtorKind = ElementType.isDestructedType();
98659d1ed5bSDimitry Andric   EHScopeStack::stable_iterator Cleanup;
98759d1ed5bSDimitry Andric   llvm::Instruction *CleanupDominator = nullptr;
988f785676fSDimitry Andric 
9890623d748SDimitry Andric   CharUnits ElementSize = getContext().getTypeSizeInChars(ElementType);
9900623d748SDimitry Andric   CharUnits ElementAlign =
9910623d748SDimitry Andric     BeginPtr.getAlignment().alignmentOfArrayElement(ElementSize);
9920623d748SDimitry Andric 
99344290647SDimitry Andric   // Attempt to perform zero-initialization using memset.
99444290647SDimitry Andric   auto TryMemsetInitialization = [&]() -> bool {
99544290647SDimitry Andric     // FIXME: If the type is a pointer-to-data-member under the Itanium ABI,
99644290647SDimitry Andric     // we can initialize with a memset to -1.
99744290647SDimitry Andric     if (!CGM.getTypes().isZeroInitializable(ElementType))
99844290647SDimitry Andric       return false;
99944290647SDimitry Andric 
100044290647SDimitry Andric     // Optimization: since zero initialization will just set the memory
100144290647SDimitry Andric     // to all zeroes, generate a single memset to do it in one shot.
100244290647SDimitry Andric 
100344290647SDimitry Andric     // Subtract out the size of any elements we've already initialized.
100444290647SDimitry Andric     auto *RemainingSize = AllocSizeWithoutCookie;
100544290647SDimitry Andric     if (InitListElements) {
100644290647SDimitry Andric       // We know this can't overflow; we check this when doing the allocation.
100744290647SDimitry Andric       auto *InitializedSize = llvm::ConstantInt::get(
100844290647SDimitry Andric           RemainingSize->getType(),
100944290647SDimitry Andric           getContext().getTypeSizeInChars(ElementType).getQuantity() *
101044290647SDimitry Andric               InitListElements);
101144290647SDimitry Andric       RemainingSize = Builder.CreateSub(RemainingSize, InitializedSize);
101244290647SDimitry Andric     }
101344290647SDimitry Andric 
101444290647SDimitry Andric     // Create the memset.
101544290647SDimitry Andric     Builder.CreateMemSet(CurPtr, Builder.getInt8(0), RemainingSize, false);
101644290647SDimitry Andric     return true;
101744290647SDimitry Andric   };
101844290647SDimitry Andric 
1019dff0c46cSDimitry Andric   // If the initializer is an initializer list, first do the explicit elements.
1020dff0c46cSDimitry Andric   if (const InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
102144290647SDimitry Andric     // Initializing from a (braced) string literal is a special case; the init
102244290647SDimitry Andric     // list element does not initialize a (single) array element.
102344290647SDimitry Andric     if (ILE->isStringLiteralInit()) {
102444290647SDimitry Andric       // Initialize the initial portion of length equal to that of the string
102544290647SDimitry Andric       // literal. The allocation must be for at least this much; we emitted a
102644290647SDimitry Andric       // check for that earlier.
102744290647SDimitry Andric       AggValueSlot Slot =
102844290647SDimitry Andric           AggValueSlot::forAddr(CurPtr, ElementType.getQualifiers(),
102944290647SDimitry Andric                                 AggValueSlot::IsDestructed,
103044290647SDimitry Andric                                 AggValueSlot::DoesNotNeedGCBarriers,
10314ba319b5SDimitry Andric                                 AggValueSlot::IsNotAliased,
10324ba319b5SDimitry Andric                                 AggValueSlot::DoesNotOverlap,
10334ba319b5SDimitry Andric                                 AggValueSlot::IsNotZeroed,
10344ba319b5SDimitry Andric                                 AggValueSlot::IsSanitizerChecked);
103544290647SDimitry Andric       EmitAggExpr(ILE->getInit(0), Slot);
103644290647SDimitry Andric 
103744290647SDimitry Andric       // Move past these elements.
103844290647SDimitry Andric       InitListElements =
103944290647SDimitry Andric           cast<ConstantArrayType>(ILE->getType()->getAsArrayTypeUnsafe())
104044290647SDimitry Andric               ->getSize().getZExtValue();
104144290647SDimitry Andric       CurPtr =
104244290647SDimitry Andric           Address(Builder.CreateInBoundsGEP(CurPtr.getPointer(),
104344290647SDimitry Andric                                             Builder.getSize(InitListElements),
104444290647SDimitry Andric                                             "string.init.end"),
104544290647SDimitry Andric                   CurPtr.getAlignment().alignmentAtOffset(InitListElements *
104644290647SDimitry Andric                                                           ElementSize));
104744290647SDimitry Andric 
104844290647SDimitry Andric       // Zero out the rest, if any remain.
104944290647SDimitry Andric       llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
105044290647SDimitry Andric       if (!ConstNum || !ConstNum->equalsInt(InitListElements)) {
105144290647SDimitry Andric         bool OK = TryMemsetInitialization();
105244290647SDimitry Andric         (void)OK;
105344290647SDimitry Andric         assert(OK && "couldn't memset character type?");
105444290647SDimitry Andric       }
105544290647SDimitry Andric       return;
105644290647SDimitry Andric     }
105744290647SDimitry Andric 
105859d1ed5bSDimitry Andric     InitListElements = ILE->getNumInits();
1059dff0c46cSDimitry Andric 
1060f785676fSDimitry Andric     // If this is a multi-dimensional array new, we will initialize multiple
1061f785676fSDimitry Andric     // elements with each init list element.
1062f785676fSDimitry Andric     QualType AllocType = E->getAllocatedType();
1063f785676fSDimitry Andric     if (const ConstantArrayType *CAT = dyn_cast_or_null<ConstantArrayType>(
1064f785676fSDimitry Andric             AllocType->getAsArrayTypeUnsafe())) {
106533956c43SDimitry Andric       ElementTy = ConvertTypeForMem(AllocType);
10660623d748SDimitry Andric       CurPtr = Builder.CreateElementBitCast(CurPtr, ElementTy);
106759d1ed5bSDimitry Andric       InitListElements *= getContext().getConstantArrayElementCount(CAT);
1068f785676fSDimitry Andric     }
1069f785676fSDimitry Andric 
107059d1ed5bSDimitry Andric     // Enter a partial-destruction Cleanup if necessary.
107159d1ed5bSDimitry Andric     if (needsEHCleanup(DtorKind)) {
107259d1ed5bSDimitry Andric       // In principle we could tell the Cleanup where we are more
1073dff0c46cSDimitry Andric       // directly, but the control flow can get so varied here that it
1074dff0c46cSDimitry Andric       // would actually be quite complex.  Therefore we go through an
1075dff0c46cSDimitry Andric       // alloca.
10760623d748SDimitry Andric       EndOfInit = CreateTempAlloca(BeginPtr.getType(), getPointerAlign(),
10770623d748SDimitry Andric                                    "array.init.end");
10780623d748SDimitry Andric       CleanupDominator = Builder.CreateStore(BeginPtr.getPointer(), EndOfInit);
10790623d748SDimitry Andric       pushIrregularPartialArrayCleanup(BeginPtr.getPointer(), EndOfInit,
10800623d748SDimitry Andric                                        ElementType, ElementAlign,
108159d1ed5bSDimitry Andric                                        getDestroyer(DtorKind));
108259d1ed5bSDimitry Andric       Cleanup = EHStack.stable_begin();
1083dff0c46cSDimitry Andric     }
1084dff0c46cSDimitry Andric 
10850623d748SDimitry Andric     CharUnits StartAlign = CurPtr.getAlignment();
1086dff0c46cSDimitry Andric     for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) {
1087dff0c46cSDimitry Andric       // Tell the cleanup that it needs to destroy up to this
1088dff0c46cSDimitry Andric       // element.  TODO: some of these stores can be trivially
1089dff0c46cSDimitry Andric       // observed to be unnecessary.
10900623d748SDimitry Andric       if (EndOfInit.isValid()) {
10910623d748SDimitry Andric         auto FinishedPtr =
10920623d748SDimitry Andric           Builder.CreateBitCast(CurPtr.getPointer(), BeginPtr.getType());
10930623d748SDimitry Andric         Builder.CreateStore(FinishedPtr, EndOfInit);
10940623d748SDimitry Andric       }
109559d1ed5bSDimitry Andric       // FIXME: If the last initializer is an incomplete initializer list for
109659d1ed5bSDimitry Andric       // an array, and we have an array filler, we can fold together the two
109759d1ed5bSDimitry Andric       // initialization loops.
1098f785676fSDimitry Andric       StoreAnyExprIntoOneUnit(*this, ILE->getInit(i),
10994ba319b5SDimitry Andric                               ILE->getInit(i)->getType(), CurPtr,
11004ba319b5SDimitry Andric                               AggValueSlot::DoesNotOverlap);
11010623d748SDimitry Andric       CurPtr = Address(Builder.CreateInBoundsGEP(CurPtr.getPointer(),
11020623d748SDimitry Andric                                                  Builder.getSize(1),
11030623d748SDimitry Andric                                                  "array.exp.next"),
11040623d748SDimitry Andric                        StartAlign.alignmentAtOffset((i + 1) * ElementSize));
1105dff0c46cSDimitry Andric     }
1106dff0c46cSDimitry Andric 
1107dff0c46cSDimitry Andric     // The remaining elements are filled with the array filler expression.
1108dff0c46cSDimitry Andric     Init = ILE->getArrayFiller();
1109f785676fSDimitry Andric 
111059d1ed5bSDimitry Andric     // Extract the initializer for the individual array elements by pulling
111159d1ed5bSDimitry Andric     // out the array filler from all the nested initializer lists. This avoids
111259d1ed5bSDimitry Andric     // generating a nested loop for the initialization.
111359d1ed5bSDimitry Andric     while (Init && Init->getType()->isConstantArrayType()) {
111459d1ed5bSDimitry Andric       auto *SubILE = dyn_cast<InitListExpr>(Init);
111559d1ed5bSDimitry Andric       if (!SubILE)
111659d1ed5bSDimitry Andric         break;
111759d1ed5bSDimitry Andric       assert(SubILE->getNumInits() == 0 && "explicit inits in array filler?");
111859d1ed5bSDimitry Andric       Init = SubILE->getArrayFiller();
1119dff0c46cSDimitry Andric     }
1120dff0c46cSDimitry Andric 
112159d1ed5bSDimitry Andric     // Switch back to initializing one base element at a time.
11220623d748SDimitry Andric     CurPtr = Builder.CreateBitCast(CurPtr, BeginPtr.getType());
112359d1ed5bSDimitry Andric   }
1124ffd1746dSEd Schouten 
112559d1ed5bSDimitry Andric   // If all elements have already been initialized, skip any further
112659d1ed5bSDimitry Andric   // initialization.
112759d1ed5bSDimitry Andric   llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
112859d1ed5bSDimitry Andric   if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {
112959d1ed5bSDimitry Andric     // If there was a Cleanup, deactivate it.
113059d1ed5bSDimitry Andric     if (CleanupDominator)
113159d1ed5bSDimitry Andric       DeactivateCleanupBlock(Cleanup, CleanupDominator);
1132dff0c46cSDimitry Andric     return;
1133dff0c46cSDimitry Andric   }
1134ffd1746dSEd Schouten 
113559d1ed5bSDimitry Andric   assert(Init && "have trailing elements to initialize but no initializer");
1136ffd1746dSEd Schouten 
113759d1ed5bSDimitry Andric   // If this is a constructor call, try to optimize it out, and failing that
113859d1ed5bSDimitry Andric   // emit a single loop to initialize all remaining elements.
113959d1ed5bSDimitry Andric   if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {
1140dff0c46cSDimitry Andric     CXXConstructorDecl *Ctor = CCE->getConstructor();
1141dff0c46cSDimitry Andric     if (Ctor->isTrivial()) {
1142e580952dSDimitry Andric       // If new expression did not specify value-initialization, then there
1143e580952dSDimitry Andric       // is no initialization.
1144dff0c46cSDimitry Andric       if (!CCE->requiresZeroInitialization() || Ctor->getParent()->isEmpty())
1145e580952dSDimitry Andric         return;
1146e580952dSDimitry Andric 
114759d1ed5bSDimitry Andric       if (TryMemsetInitialization())
1148f22ef01cSRoman Divacky         return;
1149f22ef01cSRoman Divacky     }
1150e580952dSDimitry Andric 
115159d1ed5bSDimitry Andric     // Store the new Cleanup position for irregular Cleanups.
115259d1ed5bSDimitry Andric     //
115359d1ed5bSDimitry Andric     // FIXME: Share this cleanup with the constructor call emission rather than
115459d1ed5bSDimitry Andric     // having it create a cleanup of its own.
11550623d748SDimitry Andric     if (EndOfInit.isValid())
11560623d748SDimitry Andric       Builder.CreateStore(CurPtr.getPointer(), EndOfInit);
115759d1ed5bSDimitry Andric 
115859d1ed5bSDimitry Andric     // Emit a constructor call loop to initialize the remaining elements.
115959d1ed5bSDimitry Andric     if (InitListElements)
116059d1ed5bSDimitry Andric       NumElements = Builder.CreateSub(
116159d1ed5bSDimitry Andric           NumElements,
116259d1ed5bSDimitry Andric           llvm::ConstantInt::get(NumElements->getType(), InitListElements));
116339d628a0SDimitry Andric     EmitCXXAggrConstructorCall(Ctor, NumElements, CurPtr, CCE,
11644ba319b5SDimitry Andric                                /*NewPointerIsChecked*/true,
11653861d79fSDimitry Andric                                CCE->requiresZeroInitialization());
1166e580952dSDimitry Andric     return;
1167ffd1746dSEd Schouten   }
1168f22ef01cSRoman Divacky 
116959d1ed5bSDimitry Andric   // If this is value-initialization, we can usually use memset.
117059d1ed5bSDimitry Andric   ImplicitValueInitExpr IVIE(ElementType);
117159d1ed5bSDimitry Andric   if (isa<ImplicitValueInitExpr>(Init)) {
117259d1ed5bSDimitry Andric     if (TryMemsetInitialization())
1173f22ef01cSRoman Divacky       return;
1174f22ef01cSRoman Divacky 
117559d1ed5bSDimitry Andric     // Switch to an ImplicitValueInitExpr for the element type. This handles
117659d1ed5bSDimitry Andric     // only one case: multidimensional array new of pointers to members. In
117759d1ed5bSDimitry Andric     // all other cases, we already have an initializer for the array element.
117859d1ed5bSDimitry Andric     Init = &IVIE;
117959d1ed5bSDimitry Andric   }
118059d1ed5bSDimitry Andric 
118159d1ed5bSDimitry Andric   // At this point we should have found an initializer for the individual
118259d1ed5bSDimitry Andric   // elements of the array.
118359d1ed5bSDimitry Andric   assert(getContext().hasSameUnqualifiedType(ElementType, Init->getType()) &&
118459d1ed5bSDimitry Andric          "got wrong type of element to initialize");
118559d1ed5bSDimitry Andric 
118659d1ed5bSDimitry Andric   // If we have an empty initializer list, we can usually use memset.
118759d1ed5bSDimitry Andric   if (auto *ILE = dyn_cast<InitListExpr>(Init))
118859d1ed5bSDimitry Andric     if (ILE->getNumInits() == 0 && TryMemsetInitialization())
118959d1ed5bSDimitry Andric       return;
119059d1ed5bSDimitry Andric 
11918f0fd8f6SDimitry Andric   // If we have a struct whose every field is value-initialized, we can
11928f0fd8f6SDimitry Andric   // usually use memset.
11938f0fd8f6SDimitry Andric   if (auto *ILE = dyn_cast<InitListExpr>(Init)) {
11948f0fd8f6SDimitry Andric     if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {
11958f0fd8f6SDimitry Andric       if (RType->getDecl()->isStruct()) {
1196e7145dcbSDimitry Andric         unsigned NumElements = 0;
1197e7145dcbSDimitry Andric         if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RType->getDecl()))
1198e7145dcbSDimitry Andric           NumElements = CXXRD->getNumBases();
11998f0fd8f6SDimitry Andric         for (auto *Field : RType->getDecl()->fields())
12008f0fd8f6SDimitry Andric           if (!Field->isUnnamedBitfield())
1201e7145dcbSDimitry Andric             ++NumElements;
1202e7145dcbSDimitry Andric         // FIXME: Recurse into nested InitListExprs.
1203e7145dcbSDimitry Andric         if (ILE->getNumInits() == NumElements)
12048f0fd8f6SDimitry Andric           for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i)
12058f0fd8f6SDimitry Andric             if (!isa<ImplicitValueInitExpr>(ILE->getInit(i)))
1206e7145dcbSDimitry Andric               --NumElements;
1207e7145dcbSDimitry Andric         if (ILE->getNumInits() == NumElements && TryMemsetInitialization())
12088f0fd8f6SDimitry Andric           return;
12098f0fd8f6SDimitry Andric       }
12108f0fd8f6SDimitry Andric     }
12118f0fd8f6SDimitry Andric   }
12128f0fd8f6SDimitry Andric 
121359d1ed5bSDimitry Andric   // Create the loop blocks.
121459d1ed5bSDimitry Andric   llvm::BasicBlock *EntryBB = Builder.GetInsertBlock();
121559d1ed5bSDimitry Andric   llvm::BasicBlock *LoopBB = createBasicBlock("new.loop");
121659d1ed5bSDimitry Andric   llvm::BasicBlock *ContBB = createBasicBlock("new.loop.end");
121759d1ed5bSDimitry Andric 
121859d1ed5bSDimitry Andric   // Find the end of the array, hoisted out of the loop.
121959d1ed5bSDimitry Andric   llvm::Value *EndPtr =
12200623d748SDimitry Andric     Builder.CreateInBoundsGEP(BeginPtr.getPointer(), NumElements, "array.end");
122159d1ed5bSDimitry Andric 
122259d1ed5bSDimitry Andric   // If the number of elements isn't constant, we have to now check if there is
122359d1ed5bSDimitry Andric   // anything left to initialize.
122459d1ed5bSDimitry Andric   if (!ConstNum) {
12250623d748SDimitry Andric     llvm::Value *IsEmpty =
12260623d748SDimitry Andric       Builder.CreateICmpEQ(CurPtr.getPointer(), EndPtr, "array.isempty");
122759d1ed5bSDimitry Andric     Builder.CreateCondBr(IsEmpty, ContBB, LoopBB);
122859d1ed5bSDimitry Andric   }
122959d1ed5bSDimitry Andric 
123059d1ed5bSDimitry Andric   // Enter the loop.
123159d1ed5bSDimitry Andric   EmitBlock(LoopBB);
123259d1ed5bSDimitry Andric 
123359d1ed5bSDimitry Andric   // Set up the current-element phi.
123459d1ed5bSDimitry Andric   llvm::PHINode *CurPtrPhi =
12350623d748SDimitry Andric     Builder.CreatePHI(CurPtr.getType(), 2, "array.cur");
12360623d748SDimitry Andric   CurPtrPhi->addIncoming(CurPtr.getPointer(), EntryBB);
12370623d748SDimitry Andric 
12380623d748SDimitry Andric   CurPtr = Address(CurPtrPhi, ElementAlign);
123959d1ed5bSDimitry Andric 
124059d1ed5bSDimitry Andric   // Store the new Cleanup position for irregular Cleanups.
12410623d748SDimitry Andric   if (EndOfInit.isValid())
12420623d748SDimitry Andric     Builder.CreateStore(CurPtr.getPointer(), EndOfInit);
124359d1ed5bSDimitry Andric 
124459d1ed5bSDimitry Andric   // Enter a partial-destruction Cleanup if necessary.
124559d1ed5bSDimitry Andric   if (!CleanupDominator && needsEHCleanup(DtorKind)) {
12460623d748SDimitry Andric     pushRegularPartialArrayCleanup(BeginPtr.getPointer(), CurPtr.getPointer(),
12470623d748SDimitry Andric                                    ElementType, ElementAlign,
124859d1ed5bSDimitry Andric                                    getDestroyer(DtorKind));
124959d1ed5bSDimitry Andric     Cleanup = EHStack.stable_begin();
125059d1ed5bSDimitry Andric     CleanupDominator = Builder.CreateUnreachable();
125159d1ed5bSDimitry Andric   }
125259d1ed5bSDimitry Andric 
125359d1ed5bSDimitry Andric   // Emit the initializer into this element.
12544ba319b5SDimitry Andric   StoreAnyExprIntoOneUnit(*this, Init, Init->getType(), CurPtr,
12554ba319b5SDimitry Andric                           AggValueSlot::DoesNotOverlap);
125659d1ed5bSDimitry Andric 
125759d1ed5bSDimitry Andric   // Leave the Cleanup if we entered one.
125859d1ed5bSDimitry Andric   if (CleanupDominator) {
125959d1ed5bSDimitry Andric     DeactivateCleanupBlock(Cleanup, CleanupDominator);
126059d1ed5bSDimitry Andric     CleanupDominator->eraseFromParent();
126159d1ed5bSDimitry Andric   }
126259d1ed5bSDimitry Andric 
126359d1ed5bSDimitry Andric   // Advance to the next element by adjusting the pointer type as necessary.
126459d1ed5bSDimitry Andric   llvm::Value *NextPtr =
12650623d748SDimitry Andric     Builder.CreateConstInBoundsGEP1_32(ElementTy, CurPtr.getPointer(), 1,
12660623d748SDimitry Andric                                        "array.next");
126759d1ed5bSDimitry Andric 
126859d1ed5bSDimitry Andric   // Check whether we've gotten to the end of the array and, if so,
126959d1ed5bSDimitry Andric   // exit the loop.
127059d1ed5bSDimitry Andric   llvm::Value *IsEnd = Builder.CreateICmpEQ(NextPtr, EndPtr, "array.atend");
127159d1ed5bSDimitry Andric   Builder.CreateCondBr(IsEnd, ContBB, LoopBB);
127259d1ed5bSDimitry Andric   CurPtrPhi->addIncoming(NextPtr, Builder.GetInsertBlock());
127359d1ed5bSDimitry Andric 
127459d1ed5bSDimitry Andric   EmitBlock(ContBB);
127559d1ed5bSDimitry Andric }
127659d1ed5bSDimitry Andric 
EmitNewInitializer(CodeGenFunction & CGF,const CXXNewExpr * E,QualType ElementType,llvm::Type * ElementTy,Address NewPtr,llvm::Value * NumElements,llvm::Value * AllocSizeWithoutCookie)127759d1ed5bSDimitry Andric static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
127833956c43SDimitry Andric                                QualType ElementType, llvm::Type *ElementTy,
12790623d748SDimitry Andric                                Address NewPtr, llvm::Value *NumElements,
128059d1ed5bSDimitry Andric                                llvm::Value *AllocSizeWithoutCookie) {
128133956c43SDimitry Andric   ApplyDebugLocation DL(CGF, E);
128259d1ed5bSDimitry Andric   if (E->isArray())
128333956c43SDimitry Andric     CGF.EmitNewArrayInitializer(E, ElementType, ElementTy, NewPtr, NumElements,
128459d1ed5bSDimitry Andric                                 AllocSizeWithoutCookie);
128559d1ed5bSDimitry Andric   else if (const Expr *Init = E->getInitializer())
12864ba319b5SDimitry Andric     StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr,
12874ba319b5SDimitry Andric                             AggValueSlot::DoesNotOverlap);
1288f22ef01cSRoman Divacky }
1289f22ef01cSRoman Divacky 
1290f785676fSDimitry Andric /// Emit a call to an operator new or operator delete function, as implicitly
1291f785676fSDimitry Andric /// created by new-expressions and delete-expressions.
EmitNewDeleteCall(CodeGenFunction & CGF,const FunctionDecl * CalleeDecl,const FunctionProtoType * CalleeType,const CallArgList & Args)1292f785676fSDimitry Andric static RValue EmitNewDeleteCall(CodeGenFunction &CGF,
129344290647SDimitry Andric                                 const FunctionDecl *CalleeDecl,
1294f785676fSDimitry Andric                                 const FunctionProtoType *CalleeType,
1295f785676fSDimitry Andric                                 const CallArgList &Args) {
1296f785676fSDimitry Andric   llvm::Instruction *CallOrInvoke;
129744290647SDimitry Andric   llvm::Constant *CalleePtr = CGF.CGM.GetAddrOfFunction(CalleeDecl);
1298*b5893f02SDimitry Andric   CGCallee Callee = CGCallee::forDirect(CalleePtr, GlobalDecl(CalleeDecl));
1299f785676fSDimitry Andric   RValue RV =
130039d628a0SDimitry Andric       CGF.EmitCall(CGF.CGM.getTypes().arrangeFreeFunctionCall(
130139d628a0SDimitry Andric                        Args, CalleeType, /*chainCall=*/false),
130244290647SDimitry Andric                    Callee, ReturnValueSlot(), Args, &CallOrInvoke);
1303f785676fSDimitry Andric 
1304f785676fSDimitry Andric   /// C++1y [expr.new]p10:
1305f785676fSDimitry Andric   ///   [In a new-expression,] an implementation is allowed to omit a call
1306f785676fSDimitry Andric   ///   to a replaceable global allocation function.
1307f785676fSDimitry Andric   ///
1308f785676fSDimitry Andric   /// We model such elidable calls with the 'builtin' attribute.
130944290647SDimitry Andric   llvm::Function *Fn = dyn_cast<llvm::Function>(CalleePtr);
131044290647SDimitry Andric   if (CalleeDecl->isReplaceableGlobalAllocationFunction() &&
1311f785676fSDimitry Andric       Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
1312f785676fSDimitry Andric     // FIXME: Add addAttribute to CallSite.
1313f785676fSDimitry Andric     if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(CallOrInvoke))
131420e90f04SDimitry Andric       CI->addAttribute(llvm::AttributeList::FunctionIndex,
1315f785676fSDimitry Andric                        llvm::Attribute::Builtin);
1316f785676fSDimitry Andric     else if (llvm::InvokeInst *II = dyn_cast<llvm::InvokeInst>(CallOrInvoke))
131720e90f04SDimitry Andric       II->addAttribute(llvm::AttributeList::FunctionIndex,
1318f785676fSDimitry Andric                        llvm::Attribute::Builtin);
1319f785676fSDimitry Andric     else
1320f785676fSDimitry Andric       llvm_unreachable("unexpected kind of call instruction");
1321f785676fSDimitry Andric   }
1322f785676fSDimitry Andric 
1323f785676fSDimitry Andric   return RV;
1324f785676fSDimitry Andric }
1325f785676fSDimitry Andric 
EmitBuiltinNewDeleteCall(const FunctionProtoType * Type,const CallExpr * TheCall,bool IsDelete)132659d1ed5bSDimitry Andric RValue CodeGenFunction::EmitBuiltinNewDeleteCall(const FunctionProtoType *Type,
13274ba319b5SDimitry Andric                                                  const CallExpr *TheCall,
132859d1ed5bSDimitry Andric                                                  bool IsDelete) {
132959d1ed5bSDimitry Andric   CallArgList Args;
13304ba319b5SDimitry Andric   EmitCallArgs(Args, Type->getParamTypes(), TheCall->arguments());
133159d1ed5bSDimitry Andric   // Find the allocation or deallocation function that we're calling.
133259d1ed5bSDimitry Andric   ASTContext &Ctx = getContext();
133359d1ed5bSDimitry Andric   DeclarationName Name = Ctx.DeclarationNames
133459d1ed5bSDimitry Andric       .getCXXOperatorName(IsDelete ? OO_Delete : OO_New);
13354ba319b5SDimitry Andric 
133659d1ed5bSDimitry Andric   for (auto *Decl : Ctx.getTranslationUnitDecl()->lookup(Name))
133759d1ed5bSDimitry Andric     if (auto *FD = dyn_cast<FunctionDecl>(Decl))
133859d1ed5bSDimitry Andric       if (Ctx.hasSameType(FD->getType(), QualType(Type, 0)))
13394ba319b5SDimitry Andric         return EmitNewDeleteCall(*this, FD, Type, Args);
134059d1ed5bSDimitry Andric   llvm_unreachable("predeclared global operator new/delete is missing");
134159d1ed5bSDimitry Andric }
134259d1ed5bSDimitry Andric 
13439a199699SDimitry Andric namespace {
13449a199699SDimitry Andric /// The parameters to pass to a usual operator delete.
13459a199699SDimitry Andric struct UsualDeleteParams {
13469a199699SDimitry Andric   bool DestroyingDelete = false;
13479a199699SDimitry Andric   bool Size = false;
13489a199699SDimitry Andric   bool Alignment = false;
13499a199699SDimitry Andric };
13509a199699SDimitry Andric }
13519a199699SDimitry Andric 
getUsualDeleteParams(const FunctionDecl * FD)13529a199699SDimitry Andric static UsualDeleteParams getUsualDeleteParams(const FunctionDecl *FD) {
13539a199699SDimitry Andric   UsualDeleteParams Params;
13549a199699SDimitry Andric 
13559a199699SDimitry Andric   const FunctionProtoType *FPT = FD->getType()->castAs<FunctionProtoType>();
135644290647SDimitry Andric   auto AI = FPT->param_type_begin(), AE = FPT->param_type_end();
13572754fe60SDimitry Andric 
135844290647SDimitry Andric   // The first argument is always a void*.
135944290647SDimitry Andric   ++AI;
136044290647SDimitry Andric 
13619a199699SDimitry Andric   // The next parameter may be a std::destroying_delete_t.
13629a199699SDimitry Andric   if (FD->isDestroyingOperatorDelete()) {
13639a199699SDimitry Andric     Params.DestroyingDelete = true;
13649a199699SDimitry Andric     assert(AI != AE);
13659a199699SDimitry Andric     ++AI;
13669a199699SDimitry Andric   }
136744290647SDimitry Andric 
13689a199699SDimitry Andric   // Figure out what other parameters we should be implicitly passing.
136944290647SDimitry Andric   if (AI != AE && (*AI)->isIntegerType()) {
13709a199699SDimitry Andric     Params.Size = true;
137144290647SDimitry Andric     ++AI;
137244290647SDimitry Andric   }
137344290647SDimitry Andric 
137444290647SDimitry Andric   if (AI != AE && (*AI)->isAlignValT()) {
13759a199699SDimitry Andric     Params.Alignment = true;
137644290647SDimitry Andric     ++AI;
137744290647SDimitry Andric   }
137844290647SDimitry Andric 
137944290647SDimitry Andric   assert(AI == AE && "unexpected usual deallocation function parameter");
13809a199699SDimitry Andric   return Params;
138144290647SDimitry Andric }
138244290647SDimitry Andric 
138344290647SDimitry Andric namespace {
138444290647SDimitry Andric   /// A cleanup to call the given 'operator delete' function upon abnormal
138544290647SDimitry Andric   /// exit from a new expression. Templated on a traits type that deals with
138644290647SDimitry Andric   /// ensuring that the arguments dominate the cleanup if necessary.
138744290647SDimitry Andric   template<typename Traits>
138844290647SDimitry Andric   class CallDeleteDuringNew final : public EHScopeStack::Cleanup {
138944290647SDimitry Andric     /// Type used to hold llvm::Value*s.
139044290647SDimitry Andric     typedef typename Traits::ValueTy ValueTy;
139144290647SDimitry Andric     /// Type used to hold RValues.
139244290647SDimitry Andric     typedef typename Traits::RValueTy RValueTy;
139344290647SDimitry Andric     struct PlacementArg {
139444290647SDimitry Andric       RValueTy ArgValue;
139544290647SDimitry Andric       QualType ArgType;
139644290647SDimitry Andric     };
139744290647SDimitry Andric 
139844290647SDimitry Andric     unsigned NumPlacementArgs : 31;
139944290647SDimitry Andric     unsigned PassAlignmentToPlacementDelete : 1;
140044290647SDimitry Andric     const FunctionDecl *OperatorDelete;
140144290647SDimitry Andric     ValueTy Ptr;
140244290647SDimitry Andric     ValueTy AllocSize;
140344290647SDimitry Andric     CharUnits AllocAlign;
140444290647SDimitry Andric 
getPlacementArgs()140544290647SDimitry Andric     PlacementArg *getPlacementArgs() {
140644290647SDimitry Andric       return reinterpret_cast<PlacementArg *>(this + 1);
140744290647SDimitry Andric     }
14082754fe60SDimitry Andric 
14092754fe60SDimitry Andric   public:
getExtraSize(size_t NumPlacementArgs)14102754fe60SDimitry Andric     static size_t getExtraSize(size_t NumPlacementArgs) {
141144290647SDimitry Andric       return NumPlacementArgs * sizeof(PlacementArg);
14122754fe60SDimitry Andric     }
14132754fe60SDimitry Andric 
CallDeleteDuringNew(size_t NumPlacementArgs,const FunctionDecl * OperatorDelete,ValueTy Ptr,ValueTy AllocSize,bool PassAlignmentToPlacementDelete,CharUnits AllocAlign)14142754fe60SDimitry Andric     CallDeleteDuringNew(size_t NumPlacementArgs,
141544290647SDimitry Andric                         const FunctionDecl *OperatorDelete, ValueTy Ptr,
141644290647SDimitry Andric                         ValueTy AllocSize, bool PassAlignmentToPlacementDelete,
141744290647SDimitry Andric                         CharUnits AllocAlign)
141844290647SDimitry Andric       : NumPlacementArgs(NumPlacementArgs),
141944290647SDimitry Andric         PassAlignmentToPlacementDelete(PassAlignmentToPlacementDelete),
142044290647SDimitry Andric         OperatorDelete(OperatorDelete), Ptr(Ptr), AllocSize(AllocSize),
142144290647SDimitry Andric         AllocAlign(AllocAlign) {}
14222754fe60SDimitry Andric 
setPlacementArg(unsigned I,RValueTy Arg,QualType Type)142344290647SDimitry Andric     void setPlacementArg(unsigned I, RValueTy Arg, QualType Type) {
14242754fe60SDimitry Andric       assert(I < NumPlacementArgs && "index out of range");
142544290647SDimitry Andric       getPlacementArgs()[I] = {Arg, Type};
14262754fe60SDimitry Andric     }
14272754fe60SDimitry Andric 
Emit(CodeGenFunction & CGF,Flags flags)142859d1ed5bSDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
142944290647SDimitry Andric       const FunctionProtoType *FPT =
143044290647SDimitry Andric           OperatorDelete->getType()->getAs<FunctionProtoType>();
14312754fe60SDimitry Andric       CallArgList DeleteArgs;
14322754fe60SDimitry Andric 
14339a199699SDimitry Andric       // The first argument is always a void* (or C* for a destroying operator
14349a199699SDimitry Andric       // delete for class type C).
143544290647SDimitry Andric       DeleteArgs.add(Traits::get(CGF, Ptr), FPT->getParamType(0));
14362754fe60SDimitry Andric 
143744290647SDimitry Andric       // Figure out what other parameters we should be implicitly passing.
14389a199699SDimitry Andric       UsualDeleteParams Params;
143944290647SDimitry Andric       if (NumPlacementArgs) {
144044290647SDimitry Andric         // A placement deallocation function is implicitly passed an alignment
144144290647SDimitry Andric         // if the placement allocation function was, but is never passed a size.
14429a199699SDimitry Andric         Params.Alignment = PassAlignmentToPlacementDelete;
144344290647SDimitry Andric       } else {
144444290647SDimitry Andric         // For a non-placement new-expression, 'operator delete' can take a
144544290647SDimitry Andric         // size and/or an alignment if it has the right parameters.
14469a199699SDimitry Andric         Params = getUsualDeleteParams(OperatorDelete);
14472754fe60SDimitry Andric       }
14482754fe60SDimitry Andric 
14499a199699SDimitry Andric       assert(!Params.DestroyingDelete &&
14509a199699SDimitry Andric              "should not call destroying delete in a new-expression");
14519a199699SDimitry Andric 
145244290647SDimitry Andric       // The second argument can be a std::size_t (for non-placement delete).
14539a199699SDimitry Andric       if (Params.Size)
145444290647SDimitry Andric         DeleteArgs.add(Traits::get(CGF, AllocSize),
145544290647SDimitry Andric                        CGF.getContext().getSizeType());
14562754fe60SDimitry Andric 
145744290647SDimitry Andric       // The next (second or third) argument can be a std::align_val_t, which
145844290647SDimitry Andric       // is an enum whose underlying type is std::size_t.
145944290647SDimitry Andric       // FIXME: Use the right type as the parameter type. Note that in a call
146044290647SDimitry Andric       // to operator delete(size_t, ...), we may not have it available.
14619a199699SDimitry Andric       if (Params.Alignment)
146244290647SDimitry Andric         DeleteArgs.add(RValue::get(llvm::ConstantInt::get(
146344290647SDimitry Andric                            CGF.SizeTy, AllocAlign.getQuantity())),
146444290647SDimitry Andric                        CGF.getContext().getSizeType());
14652754fe60SDimitry Andric 
14662754fe60SDimitry Andric       // Pass the rest of the arguments, which must match exactly.
14672754fe60SDimitry Andric       for (unsigned I = 0; I != NumPlacementArgs; ++I) {
146844290647SDimitry Andric         auto Arg = getPlacementArgs()[I];
146944290647SDimitry Andric         DeleteArgs.add(Traits::get(CGF, Arg.ArgValue), Arg.ArgType);
14702754fe60SDimitry Andric       }
14712754fe60SDimitry Andric 
14722754fe60SDimitry Andric       // Call 'operator delete'.
1473f785676fSDimitry Andric       EmitNewDeleteCall(CGF, OperatorDelete, FPT, DeleteArgs);
14742754fe60SDimitry Andric     }
14752754fe60SDimitry Andric   };
14762754fe60SDimitry Andric }
14772754fe60SDimitry Andric 
14782754fe60SDimitry Andric /// Enter a cleanup to call 'operator delete' if the initializer in a
14792754fe60SDimitry Andric /// new-expression throws.
EnterNewDeleteCleanup(CodeGenFunction & CGF,const CXXNewExpr * E,Address NewPtr,llvm::Value * AllocSize,CharUnits AllocAlign,const CallArgList & NewArgs)14802754fe60SDimitry Andric static void EnterNewDeleteCleanup(CodeGenFunction &CGF,
14812754fe60SDimitry Andric                                   const CXXNewExpr *E,
14820623d748SDimitry Andric                                   Address NewPtr,
14832754fe60SDimitry Andric                                   llvm::Value *AllocSize,
148444290647SDimitry Andric                                   CharUnits AllocAlign,
14852754fe60SDimitry Andric                                   const CallArgList &NewArgs) {
148644290647SDimitry Andric   unsigned NumNonPlacementArgs = E->passAlignment() ? 2 : 1;
148744290647SDimitry Andric 
14882754fe60SDimitry Andric   // If we're not inside a conditional branch, then the cleanup will
14892754fe60SDimitry Andric   // dominate and we can do the easier (and more efficient) thing.
14902754fe60SDimitry Andric   if (!CGF.isInConditionalBranch()) {
149144290647SDimitry Andric     struct DirectCleanupTraits {
149244290647SDimitry Andric       typedef llvm::Value *ValueTy;
149344290647SDimitry Andric       typedef RValue RValueTy;
149444290647SDimitry Andric       static RValue get(CodeGenFunction &, ValueTy V) { return RValue::get(V); }
149544290647SDimitry Andric       static RValue get(CodeGenFunction &, RValueTy V) { return V; }
149644290647SDimitry Andric     };
149744290647SDimitry Andric 
149844290647SDimitry Andric     typedef CallDeleteDuringNew<DirectCleanupTraits> DirectCleanup;
149944290647SDimitry Andric 
150044290647SDimitry Andric     DirectCleanup *Cleanup = CGF.EHStack
150144290647SDimitry Andric       .pushCleanupWithExtra<DirectCleanup>(EHCleanup,
15022754fe60SDimitry Andric                                            E->getNumPlacementArgs(),
15032754fe60SDimitry Andric                                            E->getOperatorDelete(),
15040623d748SDimitry Andric                                            NewPtr.getPointer(),
150544290647SDimitry Andric                                            AllocSize,
150644290647SDimitry Andric                                            E->passAlignment(),
150744290647SDimitry Andric                                            AllocAlign);
150844290647SDimitry Andric     for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
150944290647SDimitry Andric       auto &Arg = NewArgs[I + NumNonPlacementArgs];
15104ba319b5SDimitry Andric       Cleanup->setPlacementArg(I, Arg.getRValue(CGF), Arg.Ty);
151144290647SDimitry Andric     }
15122754fe60SDimitry Andric 
15132754fe60SDimitry Andric     return;
15142754fe60SDimitry Andric   }
15152754fe60SDimitry Andric 
15162754fe60SDimitry Andric   // Otherwise, we need to save all this stuff.
15172754fe60SDimitry Andric   DominatingValue<RValue>::saved_type SavedNewPtr =
15180623d748SDimitry Andric     DominatingValue<RValue>::save(CGF, RValue::get(NewPtr.getPointer()));
15192754fe60SDimitry Andric   DominatingValue<RValue>::saved_type SavedAllocSize =
15202754fe60SDimitry Andric     DominatingValue<RValue>::save(CGF, RValue::get(AllocSize));
15212754fe60SDimitry Andric 
152244290647SDimitry Andric   struct ConditionalCleanupTraits {
152344290647SDimitry Andric     typedef DominatingValue<RValue>::saved_type ValueTy;
152444290647SDimitry Andric     typedef DominatingValue<RValue>::saved_type RValueTy;
152544290647SDimitry Andric     static RValue get(CodeGenFunction &CGF, ValueTy V) {
152644290647SDimitry Andric       return V.restore(CGF);
152744290647SDimitry Andric     }
152844290647SDimitry Andric   };
152944290647SDimitry Andric   typedef CallDeleteDuringNew<ConditionalCleanupTraits> ConditionalCleanup;
153044290647SDimitry Andric 
153144290647SDimitry Andric   ConditionalCleanup *Cleanup = CGF.EHStack
153244290647SDimitry Andric     .pushCleanupWithExtra<ConditionalCleanup>(EHCleanup,
15332754fe60SDimitry Andric                                               E->getNumPlacementArgs(),
15342754fe60SDimitry Andric                                               E->getOperatorDelete(),
15352754fe60SDimitry Andric                                               SavedNewPtr,
153644290647SDimitry Andric                                               SavedAllocSize,
153744290647SDimitry Andric                                               E->passAlignment(),
153844290647SDimitry Andric                                               AllocAlign);
153944290647SDimitry Andric   for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
154044290647SDimitry Andric     auto &Arg = NewArgs[I + NumNonPlacementArgs];
15414ba319b5SDimitry Andric     Cleanup->setPlacementArg(
15424ba319b5SDimitry Andric         I, DominatingValue<RValue>::save(CGF, Arg.getRValue(CGF)), Arg.Ty);
154344290647SDimitry Andric   }
15442754fe60SDimitry Andric 
1545dff0c46cSDimitry Andric   CGF.initFullExprCleanup();
15462754fe60SDimitry Andric }
15472754fe60SDimitry Andric 
EmitCXXNewExpr(const CXXNewExpr * E)1548f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
15493b0f4066SDimitry Andric   // The element type being allocated.
15503b0f4066SDimitry Andric   QualType allocType = getContext().getBaseElementType(E->getAllocatedType());
1551e580952dSDimitry Andric 
15523b0f4066SDimitry Andric   // 1. Build a call to the allocation function.
15533b0f4066SDimitry Andric   FunctionDecl *allocator = E->getOperatorNew();
1554f22ef01cSRoman Divacky 
1555dff0c46cSDimitry Andric   // If there is a brace-initializer, cannot allocate fewer elements than inits.
1556dff0c46cSDimitry Andric   unsigned minElements = 0;
1557dff0c46cSDimitry Andric   if (E->isArray() && E->hasInitializer()) {
155844290647SDimitry Andric     const InitListExpr *ILE = dyn_cast<InitListExpr>(E->getInitializer());
155944290647SDimitry Andric     if (ILE && ILE->isStringLiteralInit())
156044290647SDimitry Andric       minElements =
156144290647SDimitry Andric           cast<ConstantArrayType>(ILE->getType()->getAsArrayTypeUnsafe())
156244290647SDimitry Andric               ->getSize().getZExtValue();
156344290647SDimitry Andric     else if (ILE)
1564dff0c46cSDimitry Andric       minElements = ILE->getNumInits();
1565dff0c46cSDimitry Andric   }
1566dff0c46cSDimitry Andric 
156759d1ed5bSDimitry Andric   llvm::Value *numElements = nullptr;
156859d1ed5bSDimitry Andric   llvm::Value *allocSizeWithoutCookie = nullptr;
15693b0f4066SDimitry Andric   llvm::Value *allocSize =
1570dff0c46cSDimitry Andric     EmitCXXNewAllocSize(*this, E, minElements, numElements,
1571dff0c46cSDimitry Andric                         allocSizeWithoutCookie);
157244290647SDimitry Andric   CharUnits allocAlign = getContext().getTypeAlignInChars(allocType);
1573f22ef01cSRoman Divacky 
15740623d748SDimitry Andric   // Emit the allocation call.  If the allocator is a global placement
15750623d748SDimitry Andric   // operator, just "inline" it directly.
15760623d748SDimitry Andric   Address allocation = Address::invalid();
15770623d748SDimitry Andric   CallArgList allocatorArgs;
15780623d748SDimitry Andric   if (allocator->isReservedGlobalPlacementOperator()) {
15790623d748SDimitry Andric     assert(E->getNumPlacementArgs() == 1);
15800623d748SDimitry Andric     const Expr *arg = *E->placement_arguments().begin();
15810623d748SDimitry Andric 
1582d8866befSDimitry Andric     LValueBaseInfo BaseInfo;
1583d8866befSDimitry Andric     allocation = EmitPointerWithAlignment(arg, &BaseInfo);
15840623d748SDimitry Andric 
15850623d748SDimitry Andric     // The pointer expression will, in many cases, be an opaque void*.
15860623d748SDimitry Andric     // In these cases, discard the computed alignment and use the
15870623d748SDimitry Andric     // formal alignment of the allocated type.
1588d8866befSDimitry Andric     if (BaseInfo.getAlignmentSource() != AlignmentSource::Decl)
158944290647SDimitry Andric       allocation = Address(allocation.getPointer(), allocAlign);
15900623d748SDimitry Andric 
15910623d748SDimitry Andric     // Set up allocatorArgs for the call to operator delete if it's not
15920623d748SDimitry Andric     // the reserved global operator.
15930623d748SDimitry Andric     if (E->getOperatorDelete() &&
15940623d748SDimitry Andric         !E->getOperatorDelete()->isReservedGlobalPlacementOperator()) {
15950623d748SDimitry Andric       allocatorArgs.add(RValue::get(allocSize), getContext().getSizeType());
15960623d748SDimitry Andric       allocatorArgs.add(RValue::get(allocation.getPointer()), arg->getType());
15970623d748SDimitry Andric     }
15980623d748SDimitry Andric 
15990623d748SDimitry Andric   } else {
16000623d748SDimitry Andric     const FunctionProtoType *allocatorType =
16010623d748SDimitry Andric       allocator->getType()->castAs<FunctionProtoType>();
160244290647SDimitry Andric     unsigned ParamsToSkip = 0;
16030623d748SDimitry Andric 
16040623d748SDimitry Andric     // The allocation size is the first argument.
16050623d748SDimitry Andric     QualType sizeType = getContext().getSizeType();
16063b0f4066SDimitry Andric     allocatorArgs.add(RValue::get(allocSize), sizeType);
160744290647SDimitry Andric     ++ParamsToSkip;
1608f22ef01cSRoman Divacky 
160944290647SDimitry Andric     if (allocSize != allocSizeWithoutCookie) {
161044290647SDimitry Andric       CharUnits cookieAlign = getSizeAlign(); // FIXME: Ask the ABI.
161144290647SDimitry Andric       allocAlign = std::max(allocAlign, cookieAlign);
161244290647SDimitry Andric     }
161344290647SDimitry Andric 
161444290647SDimitry Andric     // The allocation alignment may be passed as the second argument.
161544290647SDimitry Andric     if (E->passAlignment()) {
161644290647SDimitry Andric       QualType AlignValT = sizeType;
161744290647SDimitry Andric       if (allocatorType->getNumParams() > 1) {
161844290647SDimitry Andric         AlignValT = allocatorType->getParamType(1);
161944290647SDimitry Andric         assert(getContext().hasSameUnqualifiedType(
162044290647SDimitry Andric                    AlignValT->castAs<EnumType>()->getDecl()->getIntegerType(),
162144290647SDimitry Andric                    sizeType) &&
162244290647SDimitry Andric                "wrong type for alignment parameter");
162344290647SDimitry Andric         ++ParamsToSkip;
162444290647SDimitry Andric       } else {
162544290647SDimitry Andric         // Corner case, passing alignment to 'operator new(size_t, ...)'.
162644290647SDimitry Andric         assert(allocator->isVariadic() && "can't pass alignment to allocator");
162744290647SDimitry Andric       }
162844290647SDimitry Andric       allocatorArgs.add(
162944290647SDimitry Andric           RValue::get(llvm::ConstantInt::get(SizeTy, allocAlign.getQuantity())),
163044290647SDimitry Andric           AlignValT);
163144290647SDimitry Andric     }
163244290647SDimitry Andric 
163344290647SDimitry Andric     // FIXME: Why do we not pass a CalleeDecl here?
16340623d748SDimitry Andric     EmitCallArgs(allocatorArgs, allocatorType, E->placement_arguments(),
163520e90f04SDimitry Andric                  /*AC*/AbstractCallee(), /*ParamsToSkip*/ParamsToSkip);
1636f22ef01cSRoman Divacky 
16370623d748SDimitry Andric     RValue RV =
16380623d748SDimitry Andric       EmitNewDeleteCall(*this, allocator, allocatorType, allocatorArgs);
16390623d748SDimitry Andric 
164044290647SDimitry Andric     // If this was a call to a global replaceable allocation function that does
164144290647SDimitry Andric     // not take an alignment argument, the allocator is known to produce
164244290647SDimitry Andric     // storage that's suitably aligned for any object that fits, up to a known
164344290647SDimitry Andric     // threshold. Otherwise assume it's suitably aligned for the allocated type.
164444290647SDimitry Andric     CharUnits allocationAlign = allocAlign;
164544290647SDimitry Andric     if (!E->passAlignment() &&
164644290647SDimitry Andric         allocator->isReplaceableGlobalAllocationFunction()) {
164744290647SDimitry Andric       unsigned AllocatorAlign = llvm::PowerOf2Floor(std::min<uint64_t>(
164844290647SDimitry Andric           Target.getNewAlign(), getContext().getTypeSize(allocType)));
164944290647SDimitry Andric       allocationAlign = std::max(
165044290647SDimitry Andric           allocationAlign, getContext().toCharUnitsFromBits(AllocatorAlign));
16510623d748SDimitry Andric     }
16520623d748SDimitry Andric 
16530623d748SDimitry Andric     allocation = Address(RV.getScalarVal(), allocationAlign);
1654bd5abe19SDimitry Andric   }
1655f22ef01cSRoman Divacky 
16563b0f4066SDimitry Andric   // Emit a null check on the allocation result if the allocation
16573b0f4066SDimitry Andric   // function is allowed to return null (because it has a non-throwing
165833956c43SDimitry Andric   // exception spec or is the reserved placement new) and we have an
1659*b5893f02SDimitry Andric   // interesting initializer will be running sanitizers on the initialization.
1660*b5893f02SDimitry Andric   bool nullCheck = E->shouldNullCheckAllocation() &&
1661*b5893f02SDimitry Andric                    (!allocType.isPODType(getContext()) || E->hasInitializer() ||
1662*b5893f02SDimitry Andric                     sanitizePerformTypeCheck());
1663f22ef01cSRoman Divacky 
166459d1ed5bSDimitry Andric   llvm::BasicBlock *nullCheckBB = nullptr;
166559d1ed5bSDimitry Andric   llvm::BasicBlock *contBB = nullptr;
1666f22ef01cSRoman Divacky 
16673b0f4066SDimitry Andric   // The null-check means that the initializer is conditionally
16683b0f4066SDimitry Andric   // evaluated.
16693b0f4066SDimitry Andric   ConditionalEvaluation conditional(*this);
1670f22ef01cSRoman Divacky 
16713b0f4066SDimitry Andric   if (nullCheck) {
16723b0f4066SDimitry Andric     conditional.begin(*this);
16733b0f4066SDimitry Andric 
16743b0f4066SDimitry Andric     nullCheckBB = Builder.GetInsertBlock();
16753b0f4066SDimitry Andric     llvm::BasicBlock *notNullBB = createBasicBlock("new.notnull");
16763b0f4066SDimitry Andric     contBB = createBasicBlock("new.cont");
16773b0f4066SDimitry Andric 
16780623d748SDimitry Andric     llvm::Value *isNull =
16790623d748SDimitry Andric       Builder.CreateIsNull(allocation.getPointer(), "new.isnull");
16803b0f4066SDimitry Andric     Builder.CreateCondBr(isNull, contBB, notNullBB);
16813b0f4066SDimitry Andric     EmitBlock(notNullBB);
1682f22ef01cSRoman Divacky   }
1683f22ef01cSRoman Divacky 
16842754fe60SDimitry Andric   // If there's an operator delete, enter a cleanup to call it if an
16852754fe60SDimitry Andric   // exception is thrown.
16863b0f4066SDimitry Andric   EHScopeStack::stable_iterator operatorDeleteCleanup;
168759d1ed5bSDimitry Andric   llvm::Instruction *cleanupDominator = nullptr;
1688bd5abe19SDimitry Andric   if (E->getOperatorDelete() &&
1689bd5abe19SDimitry Andric       !E->getOperatorDelete()->isReservedGlobalPlacementOperator()) {
169044290647SDimitry Andric     EnterNewDeleteCleanup(*this, E, allocation, allocSize, allocAlign,
169144290647SDimitry Andric                           allocatorArgs);
16923b0f4066SDimitry Andric     operatorDeleteCleanup = EHStack.stable_begin();
1693dff0c46cSDimitry Andric     cleanupDominator = Builder.CreateUnreachable();
1694f22ef01cSRoman Divacky   }
1695f22ef01cSRoman Divacky 
16966122f3e6SDimitry Andric   assert((allocSize == allocSizeWithoutCookie) ==
16976122f3e6SDimitry Andric          CalculateCookiePadding(*this, E).isZero());
16986122f3e6SDimitry Andric   if (allocSize != allocSizeWithoutCookie) {
16996122f3e6SDimitry Andric     assert(E->isArray());
17006122f3e6SDimitry Andric     allocation = CGM.getCXXABI().InitializeArrayCookie(*this, allocation,
17016122f3e6SDimitry Andric                                                        numElements,
17026122f3e6SDimitry Andric                                                        E, allocType);
17036122f3e6SDimitry Andric   }
17046122f3e6SDimitry Andric 
170533956c43SDimitry Andric   llvm::Type *elementTy = ConvertTypeForMem(allocType);
17060623d748SDimitry Andric   Address result = Builder.CreateElementBitCast(allocation, elementTy);
17070623d748SDimitry Andric 
17084ba319b5SDimitry Andric   // Passing pointer through launder.invariant.group to avoid propagation of
17090623d748SDimitry Andric   // vptrs information which may be included in previous type.
1710d8866befSDimitry Andric   // To not break LTO with different optimizations levels, we do it regardless
1711d8866befSDimitry Andric   // of optimization level.
17120623d748SDimitry Andric   if (CGM.getCodeGenOpts().StrictVTablePointers &&
17130623d748SDimitry Andric       allocator->isReservedGlobalPlacementOperator())
17144ba319b5SDimitry Andric     result = Address(Builder.CreateLaunderInvariantGroup(result.getPointer()),
17150623d748SDimitry Andric                      result.getAlignment());
17162754fe60SDimitry Andric 
17174ba319b5SDimitry Andric   // Emit sanitizer checks for pointer value now, so that in the case of an
17184ba319b5SDimitry Andric   // array it was checked only once and not at each constructor call.
17194ba319b5SDimitry Andric   EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall,
17204ba319b5SDimitry Andric       E->getAllocatedTypeSourceInfo()->getTypeLoc().getBeginLoc(),
17214ba319b5SDimitry Andric       result.getPointer(), allocType);
17224ba319b5SDimitry Andric 
172333956c43SDimitry Andric   EmitNewInitializer(*this, E, allocType, elementTy, result, numElements,
17246122f3e6SDimitry Andric                      allocSizeWithoutCookie);
1725e580952dSDimitry Andric   if (E->isArray()) {
1726e580952dSDimitry Andric     // NewPtr is a pointer to the base element type.  If we're
1727e580952dSDimitry Andric     // allocating an array of arrays, we'll need to cast back to the
1728e580952dSDimitry Andric     // array pointer type.
17296122f3e6SDimitry Andric     llvm::Type *resultType = ConvertTypeForMem(E->getType());
17300623d748SDimitry Andric     if (result.getType() != resultType)
17313b0f4066SDimitry Andric       result = Builder.CreateBitCast(result, resultType);
1732f22ef01cSRoman Divacky   }
1733f22ef01cSRoman Divacky 
17342754fe60SDimitry Andric   // Deactivate the 'operator delete' cleanup if we finished
17352754fe60SDimitry Andric   // initialization.
1736dff0c46cSDimitry Andric   if (operatorDeleteCleanup.isValid()) {
1737dff0c46cSDimitry Andric     DeactivateCleanupBlock(operatorDeleteCleanup, cleanupDominator);
1738dff0c46cSDimitry Andric     cleanupDominator->eraseFromParent();
1739dff0c46cSDimitry Andric   }
17402754fe60SDimitry Andric 
17410623d748SDimitry Andric   llvm::Value *resultPtr = result.getPointer();
17423b0f4066SDimitry Andric   if (nullCheck) {
17433b0f4066SDimitry Andric     conditional.end(*this);
1744f22ef01cSRoman Divacky 
17453b0f4066SDimitry Andric     llvm::BasicBlock *notNullBB = Builder.GetInsertBlock();
17463b0f4066SDimitry Andric     EmitBlock(contBB);
1747f22ef01cSRoman Divacky 
17480623d748SDimitry Andric     llvm::PHINode *PHI = Builder.CreatePHI(resultPtr->getType(), 2);
17490623d748SDimitry Andric     PHI->addIncoming(resultPtr, notNullBB);
17500623d748SDimitry Andric     PHI->addIncoming(llvm::Constant::getNullValue(resultPtr->getType()),
17513b0f4066SDimitry Andric                      nullCheckBB);
17523b0f4066SDimitry Andric 
17530623d748SDimitry Andric     resultPtr = PHI;
1754f22ef01cSRoman Divacky   }
1755f22ef01cSRoman Divacky 
17560623d748SDimitry Andric   return resultPtr;
1757f22ef01cSRoman Divacky }
1758f22ef01cSRoman Divacky 
EmitDeleteCall(const FunctionDecl * DeleteFD,llvm::Value * Ptr,QualType DeleteTy,llvm::Value * NumElements,CharUnits CookieSize)1759f22ef01cSRoman Divacky void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD,
176044290647SDimitry Andric                                      llvm::Value *Ptr, QualType DeleteTy,
176144290647SDimitry Andric                                      llvm::Value *NumElements,
176244290647SDimitry Andric                                      CharUnits CookieSize) {
176344290647SDimitry Andric   assert((!NumElements && CookieSize.isZero()) ||
176444290647SDimitry Andric          DeleteFD->getOverloadedOperator() == OO_Array_Delete);
1765e580952dSDimitry Andric 
1766f22ef01cSRoman Divacky   const FunctionProtoType *DeleteFTy =
1767f22ef01cSRoman Divacky     DeleteFD->getType()->getAs<FunctionProtoType>();
1768f22ef01cSRoman Divacky 
1769f22ef01cSRoman Divacky   CallArgList DeleteArgs;
1770f22ef01cSRoman Divacky 
17719a199699SDimitry Andric   auto Params = getUsualDeleteParams(DeleteFD);
177244290647SDimitry Andric   auto ParamTypeIt = DeleteFTy->param_type_begin();
177344290647SDimitry Andric 
177444290647SDimitry Andric   // Pass the pointer itself.
177544290647SDimitry Andric   QualType ArgTy = *ParamTypeIt++;
1776f22ef01cSRoman Divacky   llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
17773b0f4066SDimitry Andric   DeleteArgs.add(RValue::get(DeletePtr), ArgTy);
1778f22ef01cSRoman Divacky 
17799a199699SDimitry Andric   // Pass the std::destroying_delete tag if present.
17809a199699SDimitry Andric   if (Params.DestroyingDelete) {
17819a199699SDimitry Andric     QualType DDTag = *ParamTypeIt++;
17829a199699SDimitry Andric     // Just pass an 'undef'. We expect the tag type to be an empty struct.
17839a199699SDimitry Andric     auto *V = llvm::UndefValue::get(getTypes().ConvertType(DDTag));
17849a199699SDimitry Andric     DeleteArgs.add(RValue::get(V), DDTag);
17859a199699SDimitry Andric   }
17869a199699SDimitry Andric 
178744290647SDimitry Andric   // Pass the size if the delete function has a size_t parameter.
17889a199699SDimitry Andric   if (Params.Size) {
178944290647SDimitry Andric     QualType SizeType = *ParamTypeIt++;
179044290647SDimitry Andric     CharUnits DeleteTypeSize = getContext().getTypeSizeInChars(DeleteTy);
179144290647SDimitry Andric     llvm::Value *Size = llvm::ConstantInt::get(ConvertType(SizeType),
179244290647SDimitry Andric                                                DeleteTypeSize.getQuantity());
179344290647SDimitry Andric 
179444290647SDimitry Andric     // For array new, multiply by the number of elements.
179544290647SDimitry Andric     if (NumElements)
179644290647SDimitry Andric       Size = Builder.CreateMul(Size, NumElements);
179744290647SDimitry Andric 
179844290647SDimitry Andric     // If there is a cookie, add the cookie size.
179944290647SDimitry Andric     if (!CookieSize.isZero())
180044290647SDimitry Andric       Size = Builder.CreateAdd(
180144290647SDimitry Andric           Size, llvm::ConstantInt::get(SizeTy, CookieSize.getQuantity()));
180244290647SDimitry Andric 
180344290647SDimitry Andric     DeleteArgs.add(RValue::get(Size), SizeType);
180444290647SDimitry Andric   }
180544290647SDimitry Andric 
180644290647SDimitry Andric   // Pass the alignment if the delete function has an align_val_t parameter.
18079a199699SDimitry Andric   if (Params.Alignment) {
180844290647SDimitry Andric     QualType AlignValType = *ParamTypeIt++;
180944290647SDimitry Andric     CharUnits DeleteTypeAlign = getContext().toCharUnitsFromBits(
181044290647SDimitry Andric         getContext().getTypeAlignIfKnown(DeleteTy));
181144290647SDimitry Andric     llvm::Value *Align = llvm::ConstantInt::get(ConvertType(AlignValType),
181244290647SDimitry Andric                                                 DeleteTypeAlign.getQuantity());
181344290647SDimitry Andric     DeleteArgs.add(RValue::get(Align), AlignValType);
181444290647SDimitry Andric   }
181544290647SDimitry Andric 
181644290647SDimitry Andric   assert(ParamTypeIt == DeleteFTy->param_type_end() &&
181744290647SDimitry Andric          "unknown parameter to usual delete function");
1818f22ef01cSRoman Divacky 
1819f22ef01cSRoman Divacky   // Emit the call to delete.
1820f785676fSDimitry Andric   EmitNewDeleteCall(*this, DeleteFD, DeleteFTy, DeleteArgs);
1821f22ef01cSRoman Divacky }
1822f22ef01cSRoman Divacky 
1823e580952dSDimitry Andric namespace {
1824e580952dSDimitry Andric   /// Calls the given 'operator delete' on a single object.
18250623d748SDimitry Andric   struct CallObjectDelete final : EHScopeStack::Cleanup {
1826e580952dSDimitry Andric     llvm::Value *Ptr;
1827e580952dSDimitry Andric     const FunctionDecl *OperatorDelete;
1828e580952dSDimitry Andric     QualType ElementType;
1829e580952dSDimitry Andric 
CallObjectDelete__anon31ae2d890511::CallObjectDelete1830e580952dSDimitry Andric     CallObjectDelete(llvm::Value *Ptr,
1831e580952dSDimitry Andric                      const FunctionDecl *OperatorDelete,
1832e580952dSDimitry Andric                      QualType ElementType)
1833e580952dSDimitry Andric       : Ptr(Ptr), OperatorDelete(OperatorDelete), ElementType(ElementType) {}
1834e580952dSDimitry Andric 
Emit__anon31ae2d890511::CallObjectDelete183559d1ed5bSDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
1836e580952dSDimitry Andric       CGF.EmitDeleteCall(OperatorDelete, Ptr, ElementType);
1837e580952dSDimitry Andric     }
1838e580952dSDimitry Andric   };
1839e580952dSDimitry Andric }
1840e580952dSDimitry Andric 
184139d628a0SDimitry Andric void
pushCallObjectDeleteCleanup(const FunctionDecl * OperatorDelete,llvm::Value * CompletePtr,QualType ElementType)184239d628a0SDimitry Andric CodeGenFunction::pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete,
184339d628a0SDimitry Andric                                              llvm::Value *CompletePtr,
184439d628a0SDimitry Andric                                              QualType ElementType) {
184539d628a0SDimitry Andric   EHStack.pushCleanup<CallObjectDelete>(NormalAndEHCleanup, CompletePtr,
184639d628a0SDimitry Andric                                         OperatorDelete, ElementType);
184739d628a0SDimitry Andric }
184839d628a0SDimitry Andric 
18499a199699SDimitry Andric /// Emit the code for deleting a single object with a destroying operator
18509a199699SDimitry Andric /// delete. If the element type has a non-virtual destructor, Ptr has already
18519a199699SDimitry Andric /// been converted to the type of the parameter of 'operator delete'. Otherwise
18529a199699SDimitry Andric /// Ptr points to an object of the static type.
EmitDestroyingObjectDelete(CodeGenFunction & CGF,const CXXDeleteExpr * DE,Address Ptr,QualType ElementType)18539a199699SDimitry Andric static void EmitDestroyingObjectDelete(CodeGenFunction &CGF,
18549a199699SDimitry Andric                                        const CXXDeleteExpr *DE, Address Ptr,
18559a199699SDimitry Andric                                        QualType ElementType) {
18569a199699SDimitry Andric   auto *Dtor = ElementType->getAsCXXRecordDecl()->getDestructor();
18579a199699SDimitry Andric   if (Dtor && Dtor->isVirtual())
18589a199699SDimitry Andric     CGF.CGM.getCXXABI().emitVirtualObjectDelete(CGF, DE, Ptr, ElementType,
18599a199699SDimitry Andric                                                 Dtor);
18609a199699SDimitry Andric   else
18619a199699SDimitry Andric     CGF.EmitDeleteCall(DE->getOperatorDelete(), Ptr.getPointer(), ElementType);
18629a199699SDimitry Andric }
18639a199699SDimitry Andric 
1864e580952dSDimitry Andric /// Emit the code for deleting a single object.
EmitObjectDelete(CodeGenFunction & CGF,const CXXDeleteExpr * DE,Address Ptr,QualType ElementType)1865e580952dSDimitry Andric static void EmitObjectDelete(CodeGenFunction &CGF,
186639d628a0SDimitry Andric                              const CXXDeleteExpr *DE,
18670623d748SDimitry Andric                              Address Ptr,
186839d628a0SDimitry Andric                              QualType ElementType) {
186944290647SDimitry Andric   // C++11 [expr.delete]p3:
187044290647SDimitry Andric   //   If the static type of the object to be deleted is different from its
187144290647SDimitry Andric   //   dynamic type, the static type shall be a base class of the dynamic type
187244290647SDimitry Andric   //   of the object to be deleted and the static type shall have a virtual
187344290647SDimitry Andric   //   destructor or the behavior is undefined.
187444290647SDimitry Andric   CGF.EmitTypeCheck(CodeGenFunction::TCK_MemberCall,
187544290647SDimitry Andric                     DE->getExprLoc(), Ptr.getPointer(),
187644290647SDimitry Andric                     ElementType);
187744290647SDimitry Andric 
18789a199699SDimitry Andric   const FunctionDecl *OperatorDelete = DE->getOperatorDelete();
18799a199699SDimitry Andric   assert(!OperatorDelete->isDestroyingOperatorDelete());
18809a199699SDimitry Andric 
1881e580952dSDimitry Andric   // Find the destructor for the type, if applicable.  If the
1882e580952dSDimitry Andric   // destructor is virtual, we'll just emit the vcall and return.
188359d1ed5bSDimitry Andric   const CXXDestructorDecl *Dtor = nullptr;
1884e580952dSDimitry Andric   if (const RecordType *RT = ElementType->getAs<RecordType>()) {
1885e580952dSDimitry Andric     CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
18866122f3e6SDimitry Andric     if (RD->hasDefinition() && !RD->hasTrivialDestructor()) {
1887e580952dSDimitry Andric       Dtor = RD->getDestructor();
1888e580952dSDimitry Andric 
1889e580952dSDimitry Andric       if (Dtor->isVirtual()) {
189039d628a0SDimitry Andric         CGF.CGM.getCXXABI().emitVirtualObjectDelete(CGF, DE, Ptr, ElementType,
189139d628a0SDimitry Andric                                                     Dtor);
1892e580952dSDimitry Andric         return;
1893e580952dSDimitry Andric       }
1894e580952dSDimitry Andric     }
1895e580952dSDimitry Andric   }
1896e580952dSDimitry Andric 
1897e580952dSDimitry Andric   // Make sure that we call delete even if the dtor throws.
18982754fe60SDimitry Andric   // This doesn't have to a conditional cleanup because we're going
18992754fe60SDimitry Andric   // to pop it off in a second.
1900e580952dSDimitry Andric   CGF.EHStack.pushCleanup<CallObjectDelete>(NormalAndEHCleanup,
19010623d748SDimitry Andric                                             Ptr.getPointer(),
19020623d748SDimitry Andric                                             OperatorDelete, ElementType);
1903e580952dSDimitry Andric 
1904e580952dSDimitry Andric   if (Dtor)
1905e580952dSDimitry Andric     CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
1906139f7f9bSDimitry Andric                               /*ForVirtualBase=*/false,
1907139f7f9bSDimitry Andric                               /*Delegating=*/false,
1908139f7f9bSDimitry Andric                               Ptr);
19090623d748SDimitry Andric   else if (auto Lifetime = ElementType.getObjCLifetime()) {
19100623d748SDimitry Andric     switch (Lifetime) {
191117a519f9SDimitry Andric     case Qualifiers::OCL_None:
191217a519f9SDimitry Andric     case Qualifiers::OCL_ExplicitNone:
191317a519f9SDimitry Andric     case Qualifiers::OCL_Autoreleasing:
191417a519f9SDimitry Andric       break;
191517a519f9SDimitry Andric 
19160623d748SDimitry Andric     case Qualifiers::OCL_Strong:
19170623d748SDimitry Andric       CGF.EmitARCDestroyStrong(Ptr, ARCPreciseLifetime);
191817a519f9SDimitry Andric       break;
191917a519f9SDimitry Andric 
192017a519f9SDimitry Andric     case Qualifiers::OCL_Weak:
192117a519f9SDimitry Andric       CGF.EmitARCDestroyWeak(Ptr);
192217a519f9SDimitry Andric       break;
192317a519f9SDimitry Andric     }
192417a519f9SDimitry Andric   }
1925e580952dSDimitry Andric 
1926e580952dSDimitry Andric   CGF.PopCleanupBlock();
1927e580952dSDimitry Andric }
1928e580952dSDimitry Andric 
1929e580952dSDimitry Andric namespace {
1930e580952dSDimitry Andric   /// Calls the given 'operator delete' on an array of objects.
19310623d748SDimitry Andric   struct CallArrayDelete final : EHScopeStack::Cleanup {
1932e580952dSDimitry Andric     llvm::Value *Ptr;
1933e580952dSDimitry Andric     const FunctionDecl *OperatorDelete;
1934e580952dSDimitry Andric     llvm::Value *NumElements;
1935e580952dSDimitry Andric     QualType ElementType;
1936e580952dSDimitry Andric     CharUnits CookieSize;
1937e580952dSDimitry Andric 
CallArrayDelete__anon31ae2d890611::CallArrayDelete1938e580952dSDimitry Andric     CallArrayDelete(llvm::Value *Ptr,
1939e580952dSDimitry Andric                     const FunctionDecl *OperatorDelete,
1940e580952dSDimitry Andric                     llvm::Value *NumElements,
1941e580952dSDimitry Andric                     QualType ElementType,
1942e580952dSDimitry Andric                     CharUnits CookieSize)
1943e580952dSDimitry Andric       : Ptr(Ptr), OperatorDelete(OperatorDelete), NumElements(NumElements),
1944e580952dSDimitry Andric         ElementType(ElementType), CookieSize(CookieSize) {}
1945e580952dSDimitry Andric 
Emit__anon31ae2d890611::CallArrayDelete194659d1ed5bSDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
194744290647SDimitry Andric       CGF.EmitDeleteCall(OperatorDelete, Ptr, ElementType, NumElements,
194844290647SDimitry Andric                          CookieSize);
1949e580952dSDimitry Andric     }
1950e580952dSDimitry Andric   };
1951e580952dSDimitry Andric }
1952e580952dSDimitry Andric 
1953e580952dSDimitry Andric /// Emit the code for deleting an array of objects.
EmitArrayDelete(CodeGenFunction & CGF,const CXXDeleteExpr * E,Address deletedPtr,QualType elementType)1954e580952dSDimitry Andric static void EmitArrayDelete(CodeGenFunction &CGF,
19552754fe60SDimitry Andric                             const CXXDeleteExpr *E,
19560623d748SDimitry Andric                             Address deletedPtr,
195717a519f9SDimitry Andric                             QualType elementType) {
195859d1ed5bSDimitry Andric   llvm::Value *numElements = nullptr;
195959d1ed5bSDimitry Andric   llvm::Value *allocatedPtr = nullptr;
196017a519f9SDimitry Andric   CharUnits cookieSize;
196117a519f9SDimitry Andric   CGF.CGM.getCXXABI().ReadArrayCookie(CGF, deletedPtr, E, elementType,
196217a519f9SDimitry Andric                                       numElements, allocatedPtr, cookieSize);
1963e580952dSDimitry Andric 
196417a519f9SDimitry Andric   assert(allocatedPtr && "ReadArrayCookie didn't set allocated pointer");
1965e580952dSDimitry Andric 
1966e580952dSDimitry Andric   // Make sure that we call delete even if one of the dtors throws.
196717a519f9SDimitry Andric   const FunctionDecl *operatorDelete = E->getOperatorDelete();
1968e580952dSDimitry Andric   CGF.EHStack.pushCleanup<CallArrayDelete>(NormalAndEHCleanup,
196917a519f9SDimitry Andric                                            allocatedPtr, operatorDelete,
197017a519f9SDimitry Andric                                            numElements, elementType,
197117a519f9SDimitry Andric                                            cookieSize);
1972e580952dSDimitry Andric 
197317a519f9SDimitry Andric   // Destroy the elements.
197417a519f9SDimitry Andric   if (QualType::DestructionKind dtorKind = elementType.isDestructedType()) {
197517a519f9SDimitry Andric     assert(numElements && "no element count for a type with a destructor!");
197617a519f9SDimitry Andric 
19770623d748SDimitry Andric     CharUnits elementSize = CGF.getContext().getTypeSizeInChars(elementType);
19780623d748SDimitry Andric     CharUnits elementAlign =
19790623d748SDimitry Andric       deletedPtr.getAlignment().alignmentOfArrayElement(elementSize);
19800623d748SDimitry Andric 
19810623d748SDimitry Andric     llvm::Value *arrayBegin = deletedPtr.getPointer();
198217a519f9SDimitry Andric     llvm::Value *arrayEnd =
19830623d748SDimitry Andric       CGF.Builder.CreateInBoundsGEP(arrayBegin, numElements, "delete.end");
198417a519f9SDimitry Andric 
198517a519f9SDimitry Andric     // Note that it is legal to allocate a zero-length array, and we
198617a519f9SDimitry Andric     // can never fold the check away because the length should always
198717a519f9SDimitry Andric     // come from a cookie.
19880623d748SDimitry Andric     CGF.emitArrayDestroy(arrayBegin, arrayEnd, elementType, elementAlign,
198917a519f9SDimitry Andric                          CGF.getDestroyer(dtorKind),
199017a519f9SDimitry Andric                          /*checkZeroLength*/ true,
199117a519f9SDimitry Andric                          CGF.needsEHCleanup(dtorKind));
1992e580952dSDimitry Andric   }
1993e580952dSDimitry Andric 
199417a519f9SDimitry Andric   // Pop the cleanup block.
1995e580952dSDimitry Andric   CGF.PopCleanupBlock();
1996e580952dSDimitry Andric }
1997e580952dSDimitry Andric 
EmitCXXDeleteExpr(const CXXDeleteExpr * E)1998f22ef01cSRoman Divacky void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
1999f22ef01cSRoman Divacky   const Expr *Arg = E->getArgument();
20000623d748SDimitry Andric   Address Ptr = EmitPointerWithAlignment(Arg);
2001f22ef01cSRoman Divacky 
2002f22ef01cSRoman Divacky   // Null check the pointer.
2003f22ef01cSRoman Divacky   llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
2004f22ef01cSRoman Divacky   llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
2005f22ef01cSRoman Divacky 
20060623d748SDimitry Andric   llvm::Value *IsNull = Builder.CreateIsNull(Ptr.getPointer(), "isnull");
2007f22ef01cSRoman Divacky 
2008f22ef01cSRoman Divacky   Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
2009f22ef01cSRoman Divacky   EmitBlock(DeleteNotNull);
2010f22ef01cSRoman Divacky 
20119a199699SDimitry Andric   QualType DeleteTy = E->getDestroyedType();
20129a199699SDimitry Andric 
20139a199699SDimitry Andric   // A destroying operator delete overrides the entire operation of the
20149a199699SDimitry Andric   // delete expression.
20159a199699SDimitry Andric   if (E->getOperatorDelete()->isDestroyingOperatorDelete()) {
20169a199699SDimitry Andric     EmitDestroyingObjectDelete(*this, E, Ptr, DeleteTy);
20179a199699SDimitry Andric     EmitBlock(DeleteEnd);
20189a199699SDimitry Andric     return;
20199a199699SDimitry Andric   }
20209a199699SDimitry Andric 
2021e580952dSDimitry Andric   // We might be deleting a pointer to array.  If so, GEP down to the
2022e580952dSDimitry Andric   // first non-array element.
2023e580952dSDimitry Andric   // (this assumes that A(*)[3][7] is converted to [3 x [7 x %A]]*)
2024e580952dSDimitry Andric   if (DeleteTy->isConstantArrayType()) {
2025e580952dSDimitry Andric     llvm::Value *Zero = Builder.getInt32(0);
20266122f3e6SDimitry Andric     SmallVector<llvm::Value*,8> GEP;
2027f22ef01cSRoman Divacky 
2028e580952dSDimitry Andric     GEP.push_back(Zero); // point at the outermost array
2029e580952dSDimitry Andric 
2030e580952dSDimitry Andric     // For each layer of array type we're pointing at:
2031e580952dSDimitry Andric     while (const ConstantArrayType *Arr
2032e580952dSDimitry Andric              = getContext().getAsConstantArrayType(DeleteTy)) {
2033e580952dSDimitry Andric       // 1. Unpeel the array type.
2034e580952dSDimitry Andric       DeleteTy = Arr->getElementType();
2035e580952dSDimitry Andric 
2036e580952dSDimitry Andric       // 2. GEP to the first element of the array.
2037e580952dSDimitry Andric       GEP.push_back(Zero);
2038e580952dSDimitry Andric     }
2039e580952dSDimitry Andric 
20400623d748SDimitry Andric     Ptr = Address(Builder.CreateInBoundsGEP(Ptr.getPointer(), GEP, "del.first"),
20410623d748SDimitry Andric                   Ptr.getAlignment());
2042e580952dSDimitry Andric   }
2043e580952dSDimitry Andric 
20440623d748SDimitry Andric   assert(ConvertTypeForMem(DeleteTy) == Ptr.getElementType());
2045e580952dSDimitry Andric 
2046f22ef01cSRoman Divacky   if (E->isArrayForm()) {
20472754fe60SDimitry Andric     EmitArrayDelete(*this, E, Ptr, DeleteTy);
2048e580952dSDimitry Andric   } else {
204939d628a0SDimitry Andric     EmitObjectDelete(*this, E, Ptr, DeleteTy);
2050f22ef01cSRoman Divacky   }
2051f22ef01cSRoman Divacky 
2052f22ef01cSRoman Divacky   EmitBlock(DeleteEnd);
2053f22ef01cSRoman Divacky }
2054f22ef01cSRoman Divacky 
isGLValueFromPointerDeref(const Expr * E)205559d1ed5bSDimitry Andric static bool isGLValueFromPointerDeref(const Expr *E) {
205659d1ed5bSDimitry Andric   E = E->IgnoreParens();
20573b0f4066SDimitry Andric 
205859d1ed5bSDimitry Andric   if (const auto *CE = dyn_cast<CastExpr>(E)) {
205959d1ed5bSDimitry Andric     if (!CE->getSubExpr()->isGLValue())
206059d1ed5bSDimitry Andric       return false;
206159d1ed5bSDimitry Andric     return isGLValueFromPointerDeref(CE->getSubExpr());
20623b0f4066SDimitry Andric   }
20633b0f4066SDimitry Andric 
206459d1ed5bSDimitry Andric   if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
206559d1ed5bSDimitry Andric     return isGLValueFromPointerDeref(OVE->getSourceExpr());
206659d1ed5bSDimitry Andric 
206759d1ed5bSDimitry Andric   if (const auto *BO = dyn_cast<BinaryOperator>(E))
206859d1ed5bSDimitry Andric     if (BO->getOpcode() == BO_Comma)
206959d1ed5bSDimitry Andric       return isGLValueFromPointerDeref(BO->getRHS());
207059d1ed5bSDimitry Andric 
207159d1ed5bSDimitry Andric   if (const auto *ACO = dyn_cast<AbstractConditionalOperator>(E))
207259d1ed5bSDimitry Andric     return isGLValueFromPointerDeref(ACO->getTrueExpr()) ||
207359d1ed5bSDimitry Andric            isGLValueFromPointerDeref(ACO->getFalseExpr());
207459d1ed5bSDimitry Andric 
207559d1ed5bSDimitry Andric   // C++11 [expr.sub]p1:
207659d1ed5bSDimitry Andric   //   The expression E1[E2] is identical (by definition) to *((E1)+(E2))
207759d1ed5bSDimitry Andric   if (isa<ArraySubscriptExpr>(E))
207859d1ed5bSDimitry Andric     return true;
207959d1ed5bSDimitry Andric 
208059d1ed5bSDimitry Andric   if (const auto *UO = dyn_cast<UnaryOperator>(E))
208159d1ed5bSDimitry Andric     if (UO->getOpcode() == UO_Deref)
208259d1ed5bSDimitry Andric       return true;
208359d1ed5bSDimitry Andric 
208459d1ed5bSDimitry Andric   return false;
20853b0f4066SDimitry Andric }
20863b0f4066SDimitry Andric 
EmitTypeidFromVTable(CodeGenFunction & CGF,const Expr * E,llvm::Type * StdTypeInfoPtrTy)208759d1ed5bSDimitry Andric static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,
20886122f3e6SDimitry Andric                                          llvm::Type *StdTypeInfoPtrTy) {
20893b0f4066SDimitry Andric   // Get the vtable pointer.
20900623d748SDimitry Andric   Address ThisPtr = CGF.EmitLValue(E).getAddress();
20913b0f4066SDimitry Andric 
2092fe4fed2eSDimitry Andric   QualType SrcRecordTy = E->getType();
2093fe4fed2eSDimitry Andric 
2094fe4fed2eSDimitry Andric   // C++ [class.cdtor]p4:
2095fe4fed2eSDimitry Andric   //   If the operand of typeid refers to the object under construction or
2096fe4fed2eSDimitry Andric   //   destruction and the static type of the operand is neither the constructor
2097fe4fed2eSDimitry Andric   //   or destructor’s class nor one of its bases, the behavior is undefined.
2098fe4fed2eSDimitry Andric   CGF.EmitTypeCheck(CodeGenFunction::TCK_DynamicOperation, E->getExprLoc(),
2099fe4fed2eSDimitry Andric                     ThisPtr.getPointer(), SrcRecordTy);
2100fe4fed2eSDimitry Andric 
21013b0f4066SDimitry Andric   // C++ [expr.typeid]p2:
21023b0f4066SDimitry Andric   //   If the glvalue expression is obtained by applying the unary * operator to
21033b0f4066SDimitry Andric   //   a pointer and the pointer is a null pointer value, the typeid expression
21043b0f4066SDimitry Andric   //   throws the std::bad_typeid exception.
210559d1ed5bSDimitry Andric   //
210659d1ed5bSDimitry Andric   // However, this paragraph's intent is not clear.  We choose a very generous
210759d1ed5bSDimitry Andric   // interpretation which implores us to consider comma operators, conditional
210859d1ed5bSDimitry Andric   // operators, parentheses and other such constructs.
210959d1ed5bSDimitry Andric   if (CGF.CGM.getCXXABI().shouldTypeidBeNullChecked(
211059d1ed5bSDimitry Andric           isGLValueFromPointerDeref(E), SrcRecordTy)) {
21113b0f4066SDimitry Andric     llvm::BasicBlock *BadTypeidBlock =
21123b0f4066SDimitry Andric         CGF.createBasicBlock("typeid.bad_typeid");
211359d1ed5bSDimitry Andric     llvm::BasicBlock *EndBlock = CGF.createBasicBlock("typeid.end");
21143b0f4066SDimitry Andric 
21150623d748SDimitry Andric     llvm::Value *IsNull = CGF.Builder.CreateIsNull(ThisPtr.getPointer());
21163b0f4066SDimitry Andric     CGF.Builder.CreateCondBr(IsNull, BadTypeidBlock, EndBlock);
21173b0f4066SDimitry Andric 
21183b0f4066SDimitry Andric     CGF.EmitBlock(BadTypeidBlock);
211959d1ed5bSDimitry Andric     CGF.CGM.getCXXABI().EmitBadTypeidCall(CGF);
21203b0f4066SDimitry Andric     CGF.EmitBlock(EndBlock);
21213b0f4066SDimitry Andric   }
21223b0f4066SDimitry Andric 
212359d1ed5bSDimitry Andric   return CGF.CGM.getCXXABI().EmitTypeid(CGF, SrcRecordTy, ThisPtr,
212459d1ed5bSDimitry Andric                                         StdTypeInfoPtrTy);
21253b0f4066SDimitry Andric }
21263b0f4066SDimitry Andric 
EmitCXXTypeidExpr(const CXXTypeidExpr * E)2127f22ef01cSRoman Divacky llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
21286122f3e6SDimitry Andric   llvm::Type *StdTypeInfoPtrTy =
21293b0f4066SDimitry Andric     ConvertType(E->getType())->getPointerTo();
2130f22ef01cSRoman Divacky 
2131f22ef01cSRoman Divacky   if (E->isTypeOperand()) {
2132f22ef01cSRoman Divacky     llvm::Constant *TypeInfo =
2133f785676fSDimitry Andric         CGM.GetAddrOfRTTIDescriptor(E->getTypeOperand(getContext()));
21343b0f4066SDimitry Andric     return Builder.CreateBitCast(TypeInfo, StdTypeInfoPtrTy);
2135f22ef01cSRoman Divacky   }
2136f22ef01cSRoman Divacky 
21373b0f4066SDimitry Andric   // C++ [expr.typeid]p2:
21383b0f4066SDimitry Andric   //   When typeid is applied to a glvalue expression whose type is a
21393b0f4066SDimitry Andric   //   polymorphic class type, the result refers to a std::type_info object
21403b0f4066SDimitry Andric   //   representing the type of the most derived object (that is, the dynamic
21413b0f4066SDimitry Andric   //   type) to which the glvalue refers.
21427ae0e2c9SDimitry Andric   if (E->isPotentiallyEvaluated())
21433b0f4066SDimitry Andric     return EmitTypeidFromVTable(*this, E->getExprOperand(),
21443b0f4066SDimitry Andric                                 StdTypeInfoPtrTy);
2145f22ef01cSRoman Divacky 
21463b0f4066SDimitry Andric   QualType OperandTy = E->getExprOperand()->getType();
21473b0f4066SDimitry Andric   return Builder.CreateBitCast(CGM.GetAddrOfRTTIDescriptor(OperandTy),
21483b0f4066SDimitry Andric                                StdTypeInfoPtrTy);
21493b0f4066SDimitry Andric }
21503b0f4066SDimitry Andric 
EmitDynamicCastToNull(CodeGenFunction & CGF,QualType DestTy)21513b0f4066SDimitry Andric static llvm::Value *EmitDynamicCastToNull(CodeGenFunction &CGF,
21523b0f4066SDimitry Andric                                           QualType DestTy) {
21536122f3e6SDimitry Andric   llvm::Type *DestLTy = CGF.ConvertType(DestTy);
21543b0f4066SDimitry Andric   if (DestTy->isPointerType())
21553b0f4066SDimitry Andric     return llvm::Constant::getNullValue(DestLTy);
21563b0f4066SDimitry Andric 
21573b0f4066SDimitry Andric   /// C++ [expr.dynamic.cast]p9:
21583b0f4066SDimitry Andric   ///   A failed cast to reference type throws std::bad_cast
215959d1ed5bSDimitry Andric   if (!CGF.CGM.getCXXABI().EmitBadCastCall(CGF))
216059d1ed5bSDimitry Andric     return nullptr;
21613b0f4066SDimitry Andric 
21623b0f4066SDimitry Andric   CGF.EmitBlock(CGF.createBasicBlock("dynamic_cast.end"));
21633b0f4066SDimitry Andric   return llvm::UndefValue::get(DestLTy);
21643b0f4066SDimitry Andric }
21653b0f4066SDimitry Andric 
EmitDynamicCast(Address ThisAddr,const CXXDynamicCastExpr * DCE)21660623d748SDimitry Andric llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr,
2167f22ef01cSRoman Divacky                                               const CXXDynamicCastExpr *DCE) {
21680623d748SDimitry Andric   CGM.EmitExplicitCastExprType(DCE, this);
2169f22ef01cSRoman Divacky   QualType DestTy = DCE->getTypeAsWritten();
2170f22ef01cSRoman Divacky 
21713b0f4066SDimitry Andric   QualType SrcTy = DCE->getSubExpr()->getType();
2172f22ef01cSRoman Divacky 
217359d1ed5bSDimitry Andric   // C++ [expr.dynamic.cast]p7:
217459d1ed5bSDimitry Andric   //   If T is "pointer to cv void," then the result is a pointer to the most
217559d1ed5bSDimitry Andric   //   derived object pointed to by v.
217659d1ed5bSDimitry Andric   const PointerType *DestPTy = DestTy->getAs<PointerType>();
217759d1ed5bSDimitry Andric 
217859d1ed5bSDimitry Andric   bool isDynamicCastToVoid;
217959d1ed5bSDimitry Andric   QualType SrcRecordTy;
218059d1ed5bSDimitry Andric   QualType DestRecordTy;
218159d1ed5bSDimitry Andric   if (DestPTy) {
218259d1ed5bSDimitry Andric     isDynamicCastToVoid = DestPTy->getPointeeType()->isVoidType();
218359d1ed5bSDimitry Andric     SrcRecordTy = SrcTy->castAs<PointerType>()->getPointeeType();
218459d1ed5bSDimitry Andric     DestRecordTy = DestPTy->getPointeeType();
218559d1ed5bSDimitry Andric   } else {
218659d1ed5bSDimitry Andric     isDynamicCastToVoid = false;
218759d1ed5bSDimitry Andric     SrcRecordTy = SrcTy;
218859d1ed5bSDimitry Andric     DestRecordTy = DestTy->castAs<ReferenceType>()->getPointeeType();
218959d1ed5bSDimitry Andric   }
219059d1ed5bSDimitry Andric 
2191fe4fed2eSDimitry Andric   // C++ [class.cdtor]p5:
2192fe4fed2eSDimitry Andric   //   If the operand of the dynamic_cast refers to the object under
2193fe4fed2eSDimitry Andric   //   construction or destruction and the static type of the operand is not a
2194fe4fed2eSDimitry Andric   //   pointer to or object of the constructor or destructor’s own class or one
2195fe4fed2eSDimitry Andric   //   of its bases, the dynamic_cast results in undefined behavior.
2196fe4fed2eSDimitry Andric   EmitTypeCheck(TCK_DynamicOperation, DCE->getExprLoc(), ThisAddr.getPointer(),
2197fe4fed2eSDimitry Andric                 SrcRecordTy);
2198fe4fed2eSDimitry Andric 
2199fe4fed2eSDimitry Andric   if (DCE->isAlwaysNull())
2200fe4fed2eSDimitry Andric     if (llvm::Value *T = EmitDynamicCastToNull(*this, DestTy))
2201fe4fed2eSDimitry Andric       return T;
2202fe4fed2eSDimitry Andric 
220359d1ed5bSDimitry Andric   assert(SrcRecordTy->isRecordType() && "source type must be a record type!");
220459d1ed5bSDimitry Andric 
22053b0f4066SDimitry Andric   // C++ [expr.dynamic.cast]p4:
22063b0f4066SDimitry Andric   //   If the value of v is a null pointer value in the pointer case, the result
22073b0f4066SDimitry Andric   //   is the null pointer value of type T.
220859d1ed5bSDimitry Andric   bool ShouldNullCheckSrcValue =
220959d1ed5bSDimitry Andric       CGM.getCXXABI().shouldDynamicCastCallBeNullChecked(SrcTy->isPointerType(),
221059d1ed5bSDimitry Andric                                                          SrcRecordTy);
22113b0f4066SDimitry Andric 
221259d1ed5bSDimitry Andric   llvm::BasicBlock *CastNull = nullptr;
221359d1ed5bSDimitry Andric   llvm::BasicBlock *CastNotNull = nullptr;
22143b0f4066SDimitry Andric   llvm::BasicBlock *CastEnd = createBasicBlock("dynamic_cast.end");
22153b0f4066SDimitry Andric 
22163b0f4066SDimitry Andric   if (ShouldNullCheckSrcValue) {
22173b0f4066SDimitry Andric     CastNull = createBasicBlock("dynamic_cast.null");
22183b0f4066SDimitry Andric     CastNotNull = createBasicBlock("dynamic_cast.notnull");
22193b0f4066SDimitry Andric 
22200623d748SDimitry Andric     llvm::Value *IsNull = Builder.CreateIsNull(ThisAddr.getPointer());
22213b0f4066SDimitry Andric     Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
22223b0f4066SDimitry Andric     EmitBlock(CastNotNull);
2223f22ef01cSRoman Divacky   }
2224f22ef01cSRoman Divacky 
22250623d748SDimitry Andric   llvm::Value *Value;
222659d1ed5bSDimitry Andric   if (isDynamicCastToVoid) {
22270623d748SDimitry Andric     Value = CGM.getCXXABI().EmitDynamicCastToVoid(*this, ThisAddr, SrcRecordTy,
222859d1ed5bSDimitry Andric                                                   DestTy);
222959d1ed5bSDimitry Andric   } else {
223059d1ed5bSDimitry Andric     assert(DestRecordTy->isRecordType() &&
223159d1ed5bSDimitry Andric            "destination type must be a record type!");
22320623d748SDimitry Andric     Value = CGM.getCXXABI().EmitDynamicCastCall(*this, ThisAddr, SrcRecordTy,
223359d1ed5bSDimitry Andric                                                 DestTy, DestRecordTy, CastEnd);
22340623d748SDimitry Andric     CastNotNull = Builder.GetInsertBlock();
223559d1ed5bSDimitry Andric   }
2236f22ef01cSRoman Divacky 
22373b0f4066SDimitry Andric   if (ShouldNullCheckSrcValue) {
22383b0f4066SDimitry Andric     EmitBranch(CastEnd);
2239f22ef01cSRoman Divacky 
22403b0f4066SDimitry Andric     EmitBlock(CastNull);
22413b0f4066SDimitry Andric     EmitBranch(CastEnd);
2242f22ef01cSRoman Divacky   }
2243f22ef01cSRoman Divacky 
22443b0f4066SDimitry Andric   EmitBlock(CastEnd);
2245f22ef01cSRoman Divacky 
22463b0f4066SDimitry Andric   if (ShouldNullCheckSrcValue) {
22473b0f4066SDimitry Andric     llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2);
22483b0f4066SDimitry Andric     PHI->addIncoming(Value, CastNotNull);
22493b0f4066SDimitry Andric     PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull);
2250f22ef01cSRoman Divacky 
22513b0f4066SDimitry Andric     Value = PHI;
2252f22ef01cSRoman Divacky   }
2253f22ef01cSRoman Divacky 
22543b0f4066SDimitry Andric   return Value;
2255f22ef01cSRoman Divacky }
2256dff0c46cSDimitry Andric 
EmitLambdaExpr(const LambdaExpr * E,AggValueSlot Slot)2257dff0c46cSDimitry Andric void CodeGenFunction::EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Slot) {
22580623d748SDimitry Andric   LValue SlotLV = MakeAddrLValue(Slot.getAddress(), E->getType());
2259dff0c46cSDimitry Andric 
2260dff0c46cSDimitry Andric   CXXRecordDecl::field_iterator CurField = E->getLambdaClass()->field_begin();
22610623d748SDimitry Andric   for (LambdaExpr::const_capture_init_iterator i = E->capture_init_begin(),
2262dff0c46cSDimitry Andric                                                e = E->capture_init_end();
2263dff0c46cSDimitry Andric        i != e; ++i, ++CurField) {
2264dff0c46cSDimitry Andric     // Emit initialization
2265cb4dff85SDimitry Andric     LValue LV = EmitLValueForFieldInitialization(SlotLV, *CurField);
226639d628a0SDimitry Andric     if (CurField->hasCapturedVLAType()) {
226739d628a0SDimitry Andric       auto VAT = CurField->getCapturedVLAType();
226839d628a0SDimitry Andric       EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
226939d628a0SDimitry Andric     } else {
227044290647SDimitry Andric       EmitInitializerForField(*CurField, LV, *i);
2271dff0c46cSDimitry Andric     }
2272dff0c46cSDimitry Andric   }
227339d628a0SDimitry Andric }
2274