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