xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/CodeGen/CGClass.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===--- CGClass.cpp - Emit LLVM Code for C++ classes -----------*- C++ -*-===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This contains code dealing with C++ code generation of classes
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg 
137330f729Sjoerg #include "CGBlocks.h"
147330f729Sjoerg #include "CGCXXABI.h"
157330f729Sjoerg #include "CGDebugInfo.h"
167330f729Sjoerg #include "CGRecordLayout.h"
177330f729Sjoerg #include "CodeGenFunction.h"
187330f729Sjoerg #include "TargetInfo.h"
19*e038c9c4Sjoerg #include "clang/AST/Attr.h"
207330f729Sjoerg #include "clang/AST/CXXInheritance.h"
21*e038c9c4Sjoerg #include "clang/AST/CharUnits.h"
227330f729Sjoerg #include "clang/AST/DeclTemplate.h"
237330f729Sjoerg #include "clang/AST/EvaluatedExprVisitor.h"
247330f729Sjoerg #include "clang/AST/RecordLayout.h"
257330f729Sjoerg #include "clang/AST/StmtCXX.h"
267330f729Sjoerg #include "clang/Basic/CodeGenOptions.h"
277330f729Sjoerg #include "clang/Basic/TargetBuiltins.h"
287330f729Sjoerg #include "clang/CodeGen/CGFunctionInfo.h"
297330f729Sjoerg #include "llvm/IR/Intrinsics.h"
307330f729Sjoerg #include "llvm/IR/Metadata.h"
317330f729Sjoerg #include "llvm/Transforms/Utils/SanitizerStats.h"
327330f729Sjoerg 
337330f729Sjoerg using namespace clang;
347330f729Sjoerg using namespace CodeGen;
357330f729Sjoerg 
367330f729Sjoerg /// Return the best known alignment for an unknown pointer to a
377330f729Sjoerg /// particular class.
getClassPointerAlignment(const CXXRecordDecl * RD)387330f729Sjoerg CharUnits CodeGenModule::getClassPointerAlignment(const CXXRecordDecl *RD) {
39*e038c9c4Sjoerg   if (!RD->hasDefinition())
407330f729Sjoerg     return CharUnits::One(); // Hopefully won't be used anywhere.
417330f729Sjoerg 
427330f729Sjoerg   auto &layout = getContext().getASTRecordLayout(RD);
437330f729Sjoerg 
447330f729Sjoerg   // If the class is final, then we know that the pointer points to an
457330f729Sjoerg   // object of that type and can use the full alignment.
46*e038c9c4Sjoerg   if (RD->isEffectivelyFinal())
477330f729Sjoerg     return layout.getAlignment();
487330f729Sjoerg 
497330f729Sjoerg   // Otherwise, we have to assume it could be a subclass.
507330f729Sjoerg   return layout.getNonVirtualAlignment();
517330f729Sjoerg }
52*e038c9c4Sjoerg 
53*e038c9c4Sjoerg /// Return the smallest possible amount of storage that might be allocated
54*e038c9c4Sjoerg /// starting from the beginning of an object of a particular class.
55*e038c9c4Sjoerg ///
56*e038c9c4Sjoerg /// This may be smaller than sizeof(RD) if RD has virtual base classes.
getMinimumClassObjectSize(const CXXRecordDecl * RD)57*e038c9c4Sjoerg CharUnits CodeGenModule::getMinimumClassObjectSize(const CXXRecordDecl *RD) {
58*e038c9c4Sjoerg   if (!RD->hasDefinition())
59*e038c9c4Sjoerg     return CharUnits::One();
60*e038c9c4Sjoerg 
61*e038c9c4Sjoerg   auto &layout = getContext().getASTRecordLayout(RD);
62*e038c9c4Sjoerg 
63*e038c9c4Sjoerg   // If the class is final, then we know that the pointer points to an
64*e038c9c4Sjoerg   // object of that type and can use the full alignment.
65*e038c9c4Sjoerg   if (RD->isEffectivelyFinal())
66*e038c9c4Sjoerg     return layout.getSize();
67*e038c9c4Sjoerg 
68*e038c9c4Sjoerg   // Otherwise, we have to assume it could be a subclass.
69*e038c9c4Sjoerg   return std::max(layout.getNonVirtualSize(), CharUnits::One());
707330f729Sjoerg }
717330f729Sjoerg 
727330f729Sjoerg /// Return the best known alignment for a pointer to a virtual base,
737330f729Sjoerg /// given the alignment of a pointer to the derived class.
getVBaseAlignment(CharUnits actualDerivedAlign,const CXXRecordDecl * derivedClass,const CXXRecordDecl * vbaseClass)747330f729Sjoerg CharUnits CodeGenModule::getVBaseAlignment(CharUnits actualDerivedAlign,
757330f729Sjoerg                                            const CXXRecordDecl *derivedClass,
767330f729Sjoerg                                            const CXXRecordDecl *vbaseClass) {
777330f729Sjoerg   // The basic idea here is that an underaligned derived pointer might
787330f729Sjoerg   // indicate an underaligned base pointer.
797330f729Sjoerg 
807330f729Sjoerg   assert(vbaseClass->isCompleteDefinition());
817330f729Sjoerg   auto &baseLayout = getContext().getASTRecordLayout(vbaseClass);
827330f729Sjoerg   CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment();
837330f729Sjoerg 
847330f729Sjoerg   return getDynamicOffsetAlignment(actualDerivedAlign, derivedClass,
857330f729Sjoerg                                    expectedVBaseAlign);
867330f729Sjoerg }
877330f729Sjoerg 
887330f729Sjoerg CharUnits
getDynamicOffsetAlignment(CharUnits actualBaseAlign,const CXXRecordDecl * baseDecl,CharUnits expectedTargetAlign)897330f729Sjoerg CodeGenModule::getDynamicOffsetAlignment(CharUnits actualBaseAlign,
907330f729Sjoerg                                          const CXXRecordDecl *baseDecl,
917330f729Sjoerg                                          CharUnits expectedTargetAlign) {
927330f729Sjoerg   // If the base is an incomplete type (which is, alas, possible with
937330f729Sjoerg   // member pointers), be pessimistic.
947330f729Sjoerg   if (!baseDecl->isCompleteDefinition())
957330f729Sjoerg     return std::min(actualBaseAlign, expectedTargetAlign);
967330f729Sjoerg 
977330f729Sjoerg   auto &baseLayout = getContext().getASTRecordLayout(baseDecl);
987330f729Sjoerg   CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment();
997330f729Sjoerg 
1007330f729Sjoerg   // If the class is properly aligned, assume the target offset is, too.
1017330f729Sjoerg   //
1027330f729Sjoerg   // This actually isn't necessarily the right thing to do --- if the
1037330f729Sjoerg   // class is a complete object, but it's only properly aligned for a
1047330f729Sjoerg   // base subobject, then the alignments of things relative to it are
1057330f729Sjoerg   // probably off as well.  (Note that this requires the alignment of
1067330f729Sjoerg   // the target to be greater than the NV alignment of the derived
1077330f729Sjoerg   // class.)
1087330f729Sjoerg   //
1097330f729Sjoerg   // However, our approach to this kind of under-alignment can only
1107330f729Sjoerg   // ever be best effort; after all, we're never going to propagate
1117330f729Sjoerg   // alignments through variables or parameters.  Note, in particular,
1127330f729Sjoerg   // that constructing a polymorphic type in an address that's less
1137330f729Sjoerg   // than pointer-aligned will generally trap in the constructor,
1147330f729Sjoerg   // unless we someday add some sort of attribute to change the
1157330f729Sjoerg   // assumed alignment of 'this'.  So our goal here is pretty much
1167330f729Sjoerg   // just to allow the user to explicitly say that a pointer is
1177330f729Sjoerg   // under-aligned and then safely access its fields and vtables.
1187330f729Sjoerg   if (actualBaseAlign >= expectedBaseAlign) {
1197330f729Sjoerg     return expectedTargetAlign;
1207330f729Sjoerg   }
1217330f729Sjoerg 
1227330f729Sjoerg   // Otherwise, we might be offset by an arbitrary multiple of the
1237330f729Sjoerg   // actual alignment.  The correct adjustment is to take the min of
1247330f729Sjoerg   // the two alignments.
1257330f729Sjoerg   return std::min(actualBaseAlign, expectedTargetAlign);
1267330f729Sjoerg }
1277330f729Sjoerg 
LoadCXXThisAddress()1287330f729Sjoerg Address CodeGenFunction::LoadCXXThisAddress() {
1297330f729Sjoerg   assert(CurFuncDecl && "loading 'this' without a func declaration?");
1307330f729Sjoerg   assert(isa<CXXMethodDecl>(CurFuncDecl));
1317330f729Sjoerg 
1327330f729Sjoerg   // Lazily compute CXXThisAlignment.
1337330f729Sjoerg   if (CXXThisAlignment.isZero()) {
1347330f729Sjoerg     // Just use the best known alignment for the parent.
1357330f729Sjoerg     // TODO: if we're currently emitting a complete-object ctor/dtor,
1367330f729Sjoerg     // we can always use the complete-object alignment.
1377330f729Sjoerg     auto RD = cast<CXXMethodDecl>(CurFuncDecl)->getParent();
1387330f729Sjoerg     CXXThisAlignment = CGM.getClassPointerAlignment(RD);
1397330f729Sjoerg   }
1407330f729Sjoerg 
1417330f729Sjoerg   return Address(LoadCXXThis(), CXXThisAlignment);
1427330f729Sjoerg }
1437330f729Sjoerg 
1447330f729Sjoerg /// Emit the address of a field using a member data pointer.
1457330f729Sjoerg ///
1467330f729Sjoerg /// \param E Only used for emergency diagnostics
1477330f729Sjoerg Address
EmitCXXMemberDataPointerAddress(const Expr * E,Address base,llvm::Value * memberPtr,const MemberPointerType * memberPtrType,LValueBaseInfo * BaseInfo,TBAAAccessInfo * TBAAInfo)1487330f729Sjoerg CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base,
1497330f729Sjoerg                                                  llvm::Value *memberPtr,
1507330f729Sjoerg                                       const MemberPointerType *memberPtrType,
1517330f729Sjoerg                                                  LValueBaseInfo *BaseInfo,
1527330f729Sjoerg                                                  TBAAAccessInfo *TBAAInfo) {
1537330f729Sjoerg   // Ask the ABI to compute the actual address.
1547330f729Sjoerg   llvm::Value *ptr =
1557330f729Sjoerg     CGM.getCXXABI().EmitMemberDataPointerAddress(*this, E, base,
1567330f729Sjoerg                                                  memberPtr, memberPtrType);
1577330f729Sjoerg 
1587330f729Sjoerg   QualType memberType = memberPtrType->getPointeeType();
159*e038c9c4Sjoerg   CharUnits memberAlign =
160*e038c9c4Sjoerg       CGM.getNaturalTypeAlignment(memberType, BaseInfo, TBAAInfo);
1617330f729Sjoerg   memberAlign =
1627330f729Sjoerg     CGM.getDynamicOffsetAlignment(base.getAlignment(),
1637330f729Sjoerg                             memberPtrType->getClass()->getAsCXXRecordDecl(),
1647330f729Sjoerg                                   memberAlign);
1657330f729Sjoerg   return Address(ptr, memberAlign);
1667330f729Sjoerg }
1677330f729Sjoerg 
computeNonVirtualBaseClassOffset(const CXXRecordDecl * DerivedClass,CastExpr::path_const_iterator Start,CastExpr::path_const_iterator End)1687330f729Sjoerg CharUnits CodeGenModule::computeNonVirtualBaseClassOffset(
1697330f729Sjoerg     const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start,
1707330f729Sjoerg     CastExpr::path_const_iterator End) {
1717330f729Sjoerg   CharUnits Offset = CharUnits::Zero();
1727330f729Sjoerg 
1737330f729Sjoerg   const ASTContext &Context = getContext();
1747330f729Sjoerg   const CXXRecordDecl *RD = DerivedClass;
1757330f729Sjoerg 
1767330f729Sjoerg   for (CastExpr::path_const_iterator I = Start; I != End; ++I) {
1777330f729Sjoerg     const CXXBaseSpecifier *Base = *I;
1787330f729Sjoerg     assert(!Base->isVirtual() && "Should not see virtual bases here!");
1797330f729Sjoerg 
1807330f729Sjoerg     // Get the layout.
1817330f729Sjoerg     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
1827330f729Sjoerg 
1837330f729Sjoerg     const auto *BaseDecl =
1847330f729Sjoerg         cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
1857330f729Sjoerg 
1867330f729Sjoerg     // Add the offset.
1877330f729Sjoerg     Offset += Layout.getBaseClassOffset(BaseDecl);
1887330f729Sjoerg 
1897330f729Sjoerg     RD = BaseDecl;
1907330f729Sjoerg   }
1917330f729Sjoerg 
1927330f729Sjoerg   return Offset;
1937330f729Sjoerg }
1947330f729Sjoerg 
1957330f729Sjoerg llvm::Constant *
GetNonVirtualBaseClassOffset(const CXXRecordDecl * ClassDecl,CastExpr::path_const_iterator PathBegin,CastExpr::path_const_iterator PathEnd)1967330f729Sjoerg CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
1977330f729Sjoerg                                    CastExpr::path_const_iterator PathBegin,
1987330f729Sjoerg                                    CastExpr::path_const_iterator PathEnd) {
1997330f729Sjoerg   assert(PathBegin != PathEnd && "Base path should not be empty!");
2007330f729Sjoerg 
2017330f729Sjoerg   CharUnits Offset =
2027330f729Sjoerg       computeNonVirtualBaseClassOffset(ClassDecl, PathBegin, PathEnd);
2037330f729Sjoerg   if (Offset.isZero())
2047330f729Sjoerg     return nullptr;
2057330f729Sjoerg 
2067330f729Sjoerg   llvm::Type *PtrDiffTy =
2077330f729Sjoerg   Types.ConvertType(getContext().getPointerDiffType());
2087330f729Sjoerg 
2097330f729Sjoerg   return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity());
2107330f729Sjoerg }
2117330f729Sjoerg 
2127330f729Sjoerg /// Gets the address of a direct base class within a complete object.
2137330f729Sjoerg /// This should only be used for (1) non-virtual bases or (2) virtual bases
2147330f729Sjoerg /// when the type is known to be complete (e.g. in complete destructors).
2157330f729Sjoerg ///
2167330f729Sjoerg /// The object pointed to by 'This' is assumed to be non-null.
2177330f729Sjoerg Address
GetAddressOfDirectBaseInCompleteClass(Address This,const CXXRecordDecl * Derived,const CXXRecordDecl * Base,bool BaseIsVirtual)2187330f729Sjoerg CodeGenFunction::GetAddressOfDirectBaseInCompleteClass(Address This,
2197330f729Sjoerg                                                    const CXXRecordDecl *Derived,
2207330f729Sjoerg                                                    const CXXRecordDecl *Base,
2217330f729Sjoerg                                                    bool BaseIsVirtual) {
2227330f729Sjoerg   // 'this' must be a pointer (in some address space) to Derived.
2237330f729Sjoerg   assert(This.getElementType() == ConvertType(Derived));
2247330f729Sjoerg 
2257330f729Sjoerg   // Compute the offset of the virtual base.
2267330f729Sjoerg   CharUnits Offset;
2277330f729Sjoerg   const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived);
2287330f729Sjoerg   if (BaseIsVirtual)
2297330f729Sjoerg     Offset = Layout.getVBaseClassOffset(Base);
2307330f729Sjoerg   else
2317330f729Sjoerg     Offset = Layout.getBaseClassOffset(Base);
2327330f729Sjoerg 
2337330f729Sjoerg   // Shift and cast down to the base type.
2347330f729Sjoerg   // TODO: for complete types, this should be possible with a GEP.
2357330f729Sjoerg   Address V = This;
2367330f729Sjoerg   if (!Offset.isZero()) {
2377330f729Sjoerg     V = Builder.CreateElementBitCast(V, Int8Ty);
2387330f729Sjoerg     V = Builder.CreateConstInBoundsByteGEP(V, Offset);
2397330f729Sjoerg   }
2407330f729Sjoerg   V = Builder.CreateElementBitCast(V, ConvertType(Base));
2417330f729Sjoerg 
2427330f729Sjoerg   return V;
2437330f729Sjoerg }
2447330f729Sjoerg 
2457330f729Sjoerg static Address
ApplyNonVirtualAndVirtualOffset(CodeGenFunction & CGF,Address addr,CharUnits nonVirtualOffset,llvm::Value * virtualOffset,const CXXRecordDecl * derivedClass,const CXXRecordDecl * nearestVBase)2467330f729Sjoerg ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr,
2477330f729Sjoerg                                 CharUnits nonVirtualOffset,
2487330f729Sjoerg                                 llvm::Value *virtualOffset,
2497330f729Sjoerg                                 const CXXRecordDecl *derivedClass,
2507330f729Sjoerg                                 const CXXRecordDecl *nearestVBase) {
2517330f729Sjoerg   // Assert that we have something to do.
2527330f729Sjoerg   assert(!nonVirtualOffset.isZero() || virtualOffset != nullptr);
2537330f729Sjoerg 
2547330f729Sjoerg   // Compute the offset from the static and dynamic components.
2557330f729Sjoerg   llvm::Value *baseOffset;
2567330f729Sjoerg   if (!nonVirtualOffset.isZero()) {
257*e038c9c4Sjoerg     llvm::Type *OffsetType =
258*e038c9c4Sjoerg         (CGF.CGM.getTarget().getCXXABI().isItaniumFamily() &&
259*e038c9c4Sjoerg          CGF.CGM.getItaniumVTableContext().isRelativeLayout())
260*e038c9c4Sjoerg             ? CGF.Int32Ty
261*e038c9c4Sjoerg             : CGF.PtrDiffTy;
262*e038c9c4Sjoerg     baseOffset =
263*e038c9c4Sjoerg         llvm::ConstantInt::get(OffsetType, nonVirtualOffset.getQuantity());
2647330f729Sjoerg     if (virtualOffset) {
2657330f729Sjoerg       baseOffset = CGF.Builder.CreateAdd(virtualOffset, baseOffset);
2667330f729Sjoerg     }
2677330f729Sjoerg   } else {
2687330f729Sjoerg     baseOffset = virtualOffset;
2697330f729Sjoerg   }
2707330f729Sjoerg 
2717330f729Sjoerg   // Apply the base offset.
2727330f729Sjoerg   llvm::Value *ptr = addr.getPointer();
2737330f729Sjoerg   unsigned AddrSpace = ptr->getType()->getPointerAddressSpace();
2747330f729Sjoerg   ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8Ty->getPointerTo(AddrSpace));
275*e038c9c4Sjoerg   ptr = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, ptr, baseOffset, "add.ptr");
2767330f729Sjoerg 
2777330f729Sjoerg   // If we have a virtual component, the alignment of the result will
2787330f729Sjoerg   // be relative only to the known alignment of that vbase.
2797330f729Sjoerg   CharUnits alignment;
2807330f729Sjoerg   if (virtualOffset) {
2817330f729Sjoerg     assert(nearestVBase && "virtual offset without vbase?");
2827330f729Sjoerg     alignment = CGF.CGM.getVBaseAlignment(addr.getAlignment(),
2837330f729Sjoerg                                           derivedClass, nearestVBase);
2847330f729Sjoerg   } else {
2857330f729Sjoerg     alignment = addr.getAlignment();
2867330f729Sjoerg   }
2877330f729Sjoerg   alignment = alignment.alignmentAtOffset(nonVirtualOffset);
2887330f729Sjoerg 
2897330f729Sjoerg   return Address(ptr, alignment);
2907330f729Sjoerg }
2917330f729Sjoerg 
GetAddressOfBaseClass(Address Value,const CXXRecordDecl * Derived,CastExpr::path_const_iterator PathBegin,CastExpr::path_const_iterator PathEnd,bool NullCheckValue,SourceLocation Loc)2927330f729Sjoerg Address CodeGenFunction::GetAddressOfBaseClass(
2937330f729Sjoerg     Address Value, const CXXRecordDecl *Derived,
2947330f729Sjoerg     CastExpr::path_const_iterator PathBegin,
2957330f729Sjoerg     CastExpr::path_const_iterator PathEnd, bool NullCheckValue,
2967330f729Sjoerg     SourceLocation Loc) {
2977330f729Sjoerg   assert(PathBegin != PathEnd && "Base path should not be empty!");
2987330f729Sjoerg 
2997330f729Sjoerg   CastExpr::path_const_iterator Start = PathBegin;
3007330f729Sjoerg   const CXXRecordDecl *VBase = nullptr;
3017330f729Sjoerg 
3027330f729Sjoerg   // Sema has done some convenient canonicalization here: if the
3037330f729Sjoerg   // access path involved any virtual steps, the conversion path will
3047330f729Sjoerg   // *start* with a step down to the correct virtual base subobject,
3057330f729Sjoerg   // and hence will not require any further steps.
3067330f729Sjoerg   if ((*Start)->isVirtual()) {
3077330f729Sjoerg     VBase = cast<CXXRecordDecl>(
3087330f729Sjoerg         (*Start)->getType()->castAs<RecordType>()->getDecl());
3097330f729Sjoerg     ++Start;
3107330f729Sjoerg   }
3117330f729Sjoerg 
3127330f729Sjoerg   // Compute the static offset of the ultimate destination within its
3137330f729Sjoerg   // allocating subobject (the virtual base, if there is one, or else
3147330f729Sjoerg   // the "complete" object that we see).
3157330f729Sjoerg   CharUnits NonVirtualOffset = CGM.computeNonVirtualBaseClassOffset(
3167330f729Sjoerg       VBase ? VBase : Derived, Start, PathEnd);
3177330f729Sjoerg 
3187330f729Sjoerg   // If there's a virtual step, we can sometimes "devirtualize" it.
3197330f729Sjoerg   // For now, that's limited to when the derived type is final.
3207330f729Sjoerg   // TODO: "devirtualize" this for accesses to known-complete objects.
3217330f729Sjoerg   if (VBase && Derived->hasAttr<FinalAttr>()) {
3227330f729Sjoerg     const ASTRecordLayout &layout = getContext().getASTRecordLayout(Derived);
3237330f729Sjoerg     CharUnits vBaseOffset = layout.getVBaseClassOffset(VBase);
3247330f729Sjoerg     NonVirtualOffset += vBaseOffset;
3257330f729Sjoerg     VBase = nullptr; // we no longer have a virtual step
3267330f729Sjoerg   }
3277330f729Sjoerg 
3287330f729Sjoerg   // Get the base pointer type.
3297330f729Sjoerg   llvm::Type *BasePtrTy =
3307330f729Sjoerg       ConvertType((PathEnd[-1])->getType())
3317330f729Sjoerg           ->getPointerTo(Value.getType()->getPointerAddressSpace());
3327330f729Sjoerg 
3337330f729Sjoerg   QualType DerivedTy = getContext().getRecordType(Derived);
3347330f729Sjoerg   CharUnits DerivedAlign = CGM.getClassPointerAlignment(Derived);
3357330f729Sjoerg 
3367330f729Sjoerg   // If the static offset is zero and we don't have a virtual step,
3377330f729Sjoerg   // just do a bitcast; null checks are unnecessary.
3387330f729Sjoerg   if (NonVirtualOffset.isZero() && !VBase) {
3397330f729Sjoerg     if (sanitizePerformTypeCheck()) {
3407330f729Sjoerg       SanitizerSet SkippedChecks;
3417330f729Sjoerg       SkippedChecks.set(SanitizerKind::Null, !NullCheckValue);
3427330f729Sjoerg       EmitTypeCheck(TCK_Upcast, Loc, Value.getPointer(),
3437330f729Sjoerg                     DerivedTy, DerivedAlign, SkippedChecks);
3447330f729Sjoerg     }
3457330f729Sjoerg     return Builder.CreateBitCast(Value, BasePtrTy);
3467330f729Sjoerg   }
3477330f729Sjoerg 
3487330f729Sjoerg   llvm::BasicBlock *origBB = nullptr;
3497330f729Sjoerg   llvm::BasicBlock *endBB = nullptr;
3507330f729Sjoerg 
3517330f729Sjoerg   // Skip over the offset (and the vtable load) if we're supposed to
3527330f729Sjoerg   // null-check the pointer.
3537330f729Sjoerg   if (NullCheckValue) {
3547330f729Sjoerg     origBB = Builder.GetInsertBlock();
3557330f729Sjoerg     llvm::BasicBlock *notNullBB = createBasicBlock("cast.notnull");
3567330f729Sjoerg     endBB = createBasicBlock("cast.end");
3577330f729Sjoerg 
3587330f729Sjoerg     llvm::Value *isNull = Builder.CreateIsNull(Value.getPointer());
3597330f729Sjoerg     Builder.CreateCondBr(isNull, endBB, notNullBB);
3607330f729Sjoerg     EmitBlock(notNullBB);
3617330f729Sjoerg   }
3627330f729Sjoerg 
3637330f729Sjoerg   if (sanitizePerformTypeCheck()) {
3647330f729Sjoerg     SanitizerSet SkippedChecks;
3657330f729Sjoerg     SkippedChecks.set(SanitizerKind::Null, true);
3667330f729Sjoerg     EmitTypeCheck(VBase ? TCK_UpcastToVirtualBase : TCK_Upcast, Loc,
3677330f729Sjoerg                   Value.getPointer(), DerivedTy, DerivedAlign, SkippedChecks);
3687330f729Sjoerg   }
3697330f729Sjoerg 
3707330f729Sjoerg   // Compute the virtual offset.
3717330f729Sjoerg   llvm::Value *VirtualOffset = nullptr;
3727330f729Sjoerg   if (VBase) {
3737330f729Sjoerg     VirtualOffset =
3747330f729Sjoerg       CGM.getCXXABI().GetVirtualBaseClassOffset(*this, Value, Derived, VBase);
3757330f729Sjoerg   }
3767330f729Sjoerg 
3777330f729Sjoerg   // Apply both offsets.
3787330f729Sjoerg   Value = ApplyNonVirtualAndVirtualOffset(*this, Value, NonVirtualOffset,
3797330f729Sjoerg                                           VirtualOffset, Derived, VBase);
3807330f729Sjoerg 
3817330f729Sjoerg   // Cast to the destination type.
3827330f729Sjoerg   Value = Builder.CreateBitCast(Value, BasePtrTy);
3837330f729Sjoerg 
3847330f729Sjoerg   // Build a phi if we needed a null check.
3857330f729Sjoerg   if (NullCheckValue) {
3867330f729Sjoerg     llvm::BasicBlock *notNullBB = Builder.GetInsertBlock();
3877330f729Sjoerg     Builder.CreateBr(endBB);
3887330f729Sjoerg     EmitBlock(endBB);
3897330f729Sjoerg 
3907330f729Sjoerg     llvm::PHINode *PHI = Builder.CreatePHI(BasePtrTy, 2, "cast.result");
3917330f729Sjoerg     PHI->addIncoming(Value.getPointer(), notNullBB);
3927330f729Sjoerg     PHI->addIncoming(llvm::Constant::getNullValue(BasePtrTy), origBB);
3937330f729Sjoerg     Value = Address(PHI, Value.getAlignment());
3947330f729Sjoerg   }
3957330f729Sjoerg 
3967330f729Sjoerg   return Value;
3977330f729Sjoerg }
3987330f729Sjoerg 
3997330f729Sjoerg Address
GetAddressOfDerivedClass(Address BaseAddr,const CXXRecordDecl * Derived,CastExpr::path_const_iterator PathBegin,CastExpr::path_const_iterator PathEnd,bool NullCheckValue)4007330f729Sjoerg CodeGenFunction::GetAddressOfDerivedClass(Address BaseAddr,
4017330f729Sjoerg                                           const CXXRecordDecl *Derived,
4027330f729Sjoerg                                         CastExpr::path_const_iterator PathBegin,
4037330f729Sjoerg                                           CastExpr::path_const_iterator PathEnd,
4047330f729Sjoerg                                           bool NullCheckValue) {
4057330f729Sjoerg   assert(PathBegin != PathEnd && "Base path should not be empty!");
4067330f729Sjoerg 
4077330f729Sjoerg   QualType DerivedTy =
4087330f729Sjoerg     getContext().getCanonicalType(getContext().getTagDeclType(Derived));
4097330f729Sjoerg   unsigned AddrSpace =
4107330f729Sjoerg     BaseAddr.getPointer()->getType()->getPointerAddressSpace();
4117330f729Sjoerg   llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo(AddrSpace);
4127330f729Sjoerg 
4137330f729Sjoerg   llvm::Value *NonVirtualOffset =
4147330f729Sjoerg     CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd);
4157330f729Sjoerg 
4167330f729Sjoerg   if (!NonVirtualOffset) {
4177330f729Sjoerg     // No offset, we can just cast back.
4187330f729Sjoerg     return Builder.CreateBitCast(BaseAddr, DerivedPtrTy);
4197330f729Sjoerg   }
4207330f729Sjoerg 
4217330f729Sjoerg   llvm::BasicBlock *CastNull = nullptr;
4227330f729Sjoerg   llvm::BasicBlock *CastNotNull = nullptr;
4237330f729Sjoerg   llvm::BasicBlock *CastEnd = nullptr;
4247330f729Sjoerg 
4257330f729Sjoerg   if (NullCheckValue) {
4267330f729Sjoerg     CastNull = createBasicBlock("cast.null");
4277330f729Sjoerg     CastNotNull = createBasicBlock("cast.notnull");
4287330f729Sjoerg     CastEnd = createBasicBlock("cast.end");
4297330f729Sjoerg 
4307330f729Sjoerg     llvm::Value *IsNull = Builder.CreateIsNull(BaseAddr.getPointer());
4317330f729Sjoerg     Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
4327330f729Sjoerg     EmitBlock(CastNotNull);
4337330f729Sjoerg   }
4347330f729Sjoerg 
4357330f729Sjoerg   // Apply the offset.
4367330f729Sjoerg   llvm::Value *Value = Builder.CreateBitCast(BaseAddr.getPointer(), Int8PtrTy);
437*e038c9c4Sjoerg   Value = Builder.CreateInBoundsGEP(
438*e038c9c4Sjoerg       Int8Ty, Value, Builder.CreateNeg(NonVirtualOffset), "sub.ptr");
4397330f729Sjoerg 
4407330f729Sjoerg   // Just cast.
4417330f729Sjoerg   Value = Builder.CreateBitCast(Value, DerivedPtrTy);
4427330f729Sjoerg 
4437330f729Sjoerg   // Produce a PHI if we had a null-check.
4447330f729Sjoerg   if (NullCheckValue) {
4457330f729Sjoerg     Builder.CreateBr(CastEnd);
4467330f729Sjoerg     EmitBlock(CastNull);
4477330f729Sjoerg     Builder.CreateBr(CastEnd);
4487330f729Sjoerg     EmitBlock(CastEnd);
4497330f729Sjoerg 
4507330f729Sjoerg     llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2);
4517330f729Sjoerg     PHI->addIncoming(Value, CastNotNull);
4527330f729Sjoerg     PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull);
4537330f729Sjoerg     Value = PHI;
4547330f729Sjoerg   }
4557330f729Sjoerg 
4567330f729Sjoerg   return Address(Value, CGM.getClassPointerAlignment(Derived));
4577330f729Sjoerg }
4587330f729Sjoerg 
GetVTTParameter(GlobalDecl GD,bool ForVirtualBase,bool Delegating)4597330f729Sjoerg llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD,
4607330f729Sjoerg                                               bool ForVirtualBase,
4617330f729Sjoerg                                               bool Delegating) {
4627330f729Sjoerg   if (!CGM.getCXXABI().NeedsVTTParameter(GD)) {
4637330f729Sjoerg     // This constructor/destructor does not need a VTT parameter.
4647330f729Sjoerg     return nullptr;
4657330f729Sjoerg   }
4667330f729Sjoerg 
4677330f729Sjoerg   const CXXRecordDecl *RD = cast<CXXMethodDecl>(CurCodeDecl)->getParent();
4687330f729Sjoerg   const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent();
4697330f729Sjoerg 
4707330f729Sjoerg   llvm::Value *VTT;
4717330f729Sjoerg 
4727330f729Sjoerg   uint64_t SubVTTIndex;
4737330f729Sjoerg 
4747330f729Sjoerg   if (Delegating) {
4757330f729Sjoerg     // If this is a delegating constructor call, just load the VTT.
4767330f729Sjoerg     return LoadCXXVTT();
4777330f729Sjoerg   } else if (RD == Base) {
4787330f729Sjoerg     // If the record matches the base, this is the complete ctor/dtor
4797330f729Sjoerg     // variant calling the base variant in a class with virtual bases.
4807330f729Sjoerg     assert(!CGM.getCXXABI().NeedsVTTParameter(CurGD) &&
4817330f729Sjoerg            "doing no-op VTT offset in base dtor/ctor?");
4827330f729Sjoerg     assert(!ForVirtualBase && "Can't have same class as virtual base!");
4837330f729Sjoerg     SubVTTIndex = 0;
4847330f729Sjoerg   } else {
4857330f729Sjoerg     const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
4867330f729Sjoerg     CharUnits BaseOffset = ForVirtualBase ?
4877330f729Sjoerg       Layout.getVBaseClassOffset(Base) :
4887330f729Sjoerg       Layout.getBaseClassOffset(Base);
4897330f729Sjoerg 
4907330f729Sjoerg     SubVTTIndex =
4917330f729Sjoerg       CGM.getVTables().getSubVTTIndex(RD, BaseSubobject(Base, BaseOffset));
4927330f729Sjoerg     assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
4937330f729Sjoerg   }
4947330f729Sjoerg 
4957330f729Sjoerg   if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {
4967330f729Sjoerg     // A VTT parameter was passed to the constructor, use it.
4977330f729Sjoerg     VTT = LoadCXXVTT();
4987330f729Sjoerg     VTT = Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
4997330f729Sjoerg   } else {
5007330f729Sjoerg     // We're the complete constructor, so get the VTT by name.
5017330f729Sjoerg     VTT = CGM.getVTables().GetAddrOfVTT(RD);
5027330f729Sjoerg     VTT = Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex);
5037330f729Sjoerg   }
5047330f729Sjoerg 
5057330f729Sjoerg   return VTT;
5067330f729Sjoerg }
5077330f729Sjoerg 
5087330f729Sjoerg namespace {
5097330f729Sjoerg   /// Call the destructor for a direct base class.
5107330f729Sjoerg   struct CallBaseDtor final : EHScopeStack::Cleanup {
5117330f729Sjoerg     const CXXRecordDecl *BaseClass;
5127330f729Sjoerg     bool BaseIsVirtual;
CallBaseDtor__anonb72786c90111::CallBaseDtor5137330f729Sjoerg     CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual)
5147330f729Sjoerg       : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {}
5157330f729Sjoerg 
Emit__anonb72786c90111::CallBaseDtor5167330f729Sjoerg     void Emit(CodeGenFunction &CGF, Flags flags) override {
5177330f729Sjoerg       const CXXRecordDecl *DerivedClass =
5187330f729Sjoerg         cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent();
5197330f729Sjoerg 
5207330f729Sjoerg       const CXXDestructorDecl *D = BaseClass->getDestructor();
5217330f729Sjoerg       // We are already inside a destructor, so presumably the object being
5227330f729Sjoerg       // destroyed should have the expected type.
5237330f729Sjoerg       QualType ThisTy = D->getThisObjectType();
5247330f729Sjoerg       Address Addr =
5257330f729Sjoerg         CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThisAddress(),
5267330f729Sjoerg                                                   DerivedClass, BaseClass,
5277330f729Sjoerg                                                   BaseIsVirtual);
5287330f729Sjoerg       CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual,
5297330f729Sjoerg                                 /*Delegating=*/false, Addr, ThisTy);
5307330f729Sjoerg     }
5317330f729Sjoerg   };
5327330f729Sjoerg 
5337330f729Sjoerg   /// A visitor which checks whether an initializer uses 'this' in a
5347330f729Sjoerg   /// way which requires the vtable to be properly set.
5357330f729Sjoerg   struct DynamicThisUseChecker : ConstEvaluatedExprVisitor<DynamicThisUseChecker> {
5367330f729Sjoerg     typedef ConstEvaluatedExprVisitor<DynamicThisUseChecker> super;
5377330f729Sjoerg 
5387330f729Sjoerg     bool UsesThis;
5397330f729Sjoerg 
DynamicThisUseChecker__anonb72786c90111::DynamicThisUseChecker5407330f729Sjoerg     DynamicThisUseChecker(const ASTContext &C) : super(C), UsesThis(false) {}
5417330f729Sjoerg 
5427330f729Sjoerg     // Black-list all explicit and implicit references to 'this'.
5437330f729Sjoerg     //
5447330f729Sjoerg     // Do we need to worry about external references to 'this' derived
5457330f729Sjoerg     // from arbitrary code?  If so, then anything which runs arbitrary
5467330f729Sjoerg     // external code might potentially access the vtable.
VisitCXXThisExpr__anonb72786c90111::DynamicThisUseChecker5477330f729Sjoerg     void VisitCXXThisExpr(const CXXThisExpr *E) { UsesThis = true; }
5487330f729Sjoerg   };
5497330f729Sjoerg } // end anonymous namespace
5507330f729Sjoerg 
BaseInitializerUsesThis(ASTContext & C,const Expr * Init)5517330f729Sjoerg static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) {
5527330f729Sjoerg   DynamicThisUseChecker Checker(C);
5537330f729Sjoerg   Checker.Visit(Init);
5547330f729Sjoerg   return Checker.UsesThis;
5557330f729Sjoerg }
5567330f729Sjoerg 
EmitBaseInitializer(CodeGenFunction & CGF,const CXXRecordDecl * ClassDecl,CXXCtorInitializer * BaseInit)5577330f729Sjoerg static void EmitBaseInitializer(CodeGenFunction &CGF,
5587330f729Sjoerg                                 const CXXRecordDecl *ClassDecl,
5597330f729Sjoerg                                 CXXCtorInitializer *BaseInit) {
5607330f729Sjoerg   assert(BaseInit->isBaseInitializer() &&
5617330f729Sjoerg          "Must have base initializer!");
5627330f729Sjoerg 
5637330f729Sjoerg   Address ThisPtr = CGF.LoadCXXThisAddress();
5647330f729Sjoerg 
5657330f729Sjoerg   const Type *BaseType = BaseInit->getBaseClass();
5667330f729Sjoerg   const auto *BaseClassDecl =
5677330f729Sjoerg       cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl());
5687330f729Sjoerg 
5697330f729Sjoerg   bool isBaseVirtual = BaseInit->isBaseVirtual();
5707330f729Sjoerg 
5717330f729Sjoerg   // If the initializer for the base (other than the constructor
5727330f729Sjoerg   // itself) accesses 'this' in any way, we need to initialize the
5737330f729Sjoerg   // vtables.
5747330f729Sjoerg   if (BaseInitializerUsesThis(CGF.getContext(), BaseInit->getInit()))
5757330f729Sjoerg     CGF.InitializeVTablePointers(ClassDecl);
5767330f729Sjoerg 
5777330f729Sjoerg   // We can pretend to be a complete class because it only matters for
5787330f729Sjoerg   // virtual bases, and we only do virtual bases for complete ctors.
5797330f729Sjoerg   Address V =
5807330f729Sjoerg     CGF.GetAddressOfDirectBaseInCompleteClass(ThisPtr, ClassDecl,
5817330f729Sjoerg                                               BaseClassDecl,
5827330f729Sjoerg                                               isBaseVirtual);
5837330f729Sjoerg   AggValueSlot AggSlot =
5847330f729Sjoerg       AggValueSlot::forAddr(
5857330f729Sjoerg           V, Qualifiers(),
5867330f729Sjoerg           AggValueSlot::IsDestructed,
5877330f729Sjoerg           AggValueSlot::DoesNotNeedGCBarriers,
5887330f729Sjoerg           AggValueSlot::IsNotAliased,
5897330f729Sjoerg           CGF.getOverlapForBaseInit(ClassDecl, BaseClassDecl, isBaseVirtual));
5907330f729Sjoerg 
5917330f729Sjoerg   CGF.EmitAggExpr(BaseInit->getInit(), AggSlot);
5927330f729Sjoerg 
5937330f729Sjoerg   if (CGF.CGM.getLangOpts().Exceptions &&
5947330f729Sjoerg       !BaseClassDecl->hasTrivialDestructor())
5957330f729Sjoerg     CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl,
5967330f729Sjoerg                                           isBaseVirtual);
5977330f729Sjoerg }
5987330f729Sjoerg 
isMemcpyEquivalentSpecialMember(const CXXMethodDecl * D)5997330f729Sjoerg static bool isMemcpyEquivalentSpecialMember(const CXXMethodDecl *D) {
6007330f729Sjoerg   auto *CD = dyn_cast<CXXConstructorDecl>(D);
6017330f729Sjoerg   if (!(CD && CD->isCopyOrMoveConstructor()) &&
6027330f729Sjoerg       !D->isCopyAssignmentOperator() && !D->isMoveAssignmentOperator())
6037330f729Sjoerg     return false;
6047330f729Sjoerg 
6057330f729Sjoerg   // We can emit a memcpy for a trivial copy or move constructor/assignment.
6067330f729Sjoerg   if (D->isTrivial() && !D->getParent()->mayInsertExtraPadding())
6077330f729Sjoerg     return true;
6087330f729Sjoerg 
6097330f729Sjoerg   // We *must* emit a memcpy for a defaulted union copy or move op.
6107330f729Sjoerg   if (D->getParent()->isUnion() && D->isDefaulted())
6117330f729Sjoerg     return true;
6127330f729Sjoerg 
6137330f729Sjoerg   return false;
6147330f729Sjoerg }
6157330f729Sjoerg 
EmitLValueForAnyFieldInitialization(CodeGenFunction & CGF,CXXCtorInitializer * MemberInit,LValue & LHS)6167330f729Sjoerg static void EmitLValueForAnyFieldInitialization(CodeGenFunction &CGF,
6177330f729Sjoerg                                                 CXXCtorInitializer *MemberInit,
6187330f729Sjoerg                                                 LValue &LHS) {
6197330f729Sjoerg   FieldDecl *Field = MemberInit->getAnyMember();
6207330f729Sjoerg   if (MemberInit->isIndirectMemberInitializer()) {
6217330f729Sjoerg     // If we are initializing an anonymous union field, drill down to the field.
6227330f729Sjoerg     IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember();
6237330f729Sjoerg     for (const auto *I : IndirectField->chain())
6247330f729Sjoerg       LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(I));
6257330f729Sjoerg   } else {
6267330f729Sjoerg     LHS = CGF.EmitLValueForFieldInitialization(LHS, Field);
6277330f729Sjoerg   }
6287330f729Sjoerg }
6297330f729Sjoerg 
EmitMemberInitializer(CodeGenFunction & CGF,const CXXRecordDecl * ClassDecl,CXXCtorInitializer * MemberInit,const CXXConstructorDecl * Constructor,FunctionArgList & Args)6307330f729Sjoerg static void EmitMemberInitializer(CodeGenFunction &CGF,
6317330f729Sjoerg                                   const CXXRecordDecl *ClassDecl,
6327330f729Sjoerg                                   CXXCtorInitializer *MemberInit,
6337330f729Sjoerg                                   const CXXConstructorDecl *Constructor,
6347330f729Sjoerg                                   FunctionArgList &Args) {
6357330f729Sjoerg   ApplyDebugLocation Loc(CGF, MemberInit->getSourceLocation());
6367330f729Sjoerg   assert(MemberInit->isAnyMemberInitializer() &&
6377330f729Sjoerg          "Must have member initializer!");
6387330f729Sjoerg   assert(MemberInit->getInit() && "Must have initializer!");
6397330f729Sjoerg 
6407330f729Sjoerg   // non-static data member initializers.
6417330f729Sjoerg   FieldDecl *Field = MemberInit->getAnyMember();
6427330f729Sjoerg   QualType FieldType = Field->getType();
6437330f729Sjoerg 
6447330f729Sjoerg   llvm::Value *ThisPtr = CGF.LoadCXXThis();
6457330f729Sjoerg   QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
6467330f729Sjoerg   LValue LHS;
6477330f729Sjoerg 
6487330f729Sjoerg   // If a base constructor is being emitted, create an LValue that has the
6497330f729Sjoerg   // non-virtual alignment.
6507330f729Sjoerg   if (CGF.CurGD.getCtorType() == Ctor_Base)
6517330f729Sjoerg     LHS = CGF.MakeNaturalAlignPointeeAddrLValue(ThisPtr, RecordTy);
6527330f729Sjoerg   else
6537330f729Sjoerg     LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy);
6547330f729Sjoerg 
6557330f729Sjoerg   EmitLValueForAnyFieldInitialization(CGF, MemberInit, LHS);
6567330f729Sjoerg 
6577330f729Sjoerg   // Special case: if we are in a copy or move constructor, and we are copying
6587330f729Sjoerg   // an array of PODs or classes with trivial copy constructors, ignore the
6597330f729Sjoerg   // AST and perform the copy we know is equivalent.
6607330f729Sjoerg   // FIXME: This is hacky at best... if we had a bit more explicit information
6617330f729Sjoerg   // in the AST, we could generalize it more easily.
6627330f729Sjoerg   const ConstantArrayType *Array
6637330f729Sjoerg     = CGF.getContext().getAsConstantArrayType(FieldType);
6647330f729Sjoerg   if (Array && Constructor->isDefaulted() &&
6657330f729Sjoerg       Constructor->isCopyOrMoveConstructor()) {
6667330f729Sjoerg     QualType BaseElementTy = CGF.getContext().getBaseElementType(Array);
6677330f729Sjoerg     CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit());
6687330f729Sjoerg     if (BaseElementTy.isPODType(CGF.getContext()) ||
6697330f729Sjoerg         (CE && isMemcpyEquivalentSpecialMember(CE->getConstructor()))) {
6707330f729Sjoerg       unsigned SrcArgIndex =
6717330f729Sjoerg           CGF.CGM.getCXXABI().getSrcArgforCopyCtor(Constructor, Args);
6727330f729Sjoerg       llvm::Value *SrcPtr
6737330f729Sjoerg         = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex]));
6747330f729Sjoerg       LValue ThisRHSLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy);
6757330f729Sjoerg       LValue Src = CGF.EmitLValueForFieldInitialization(ThisRHSLV, Field);
6767330f729Sjoerg 
6777330f729Sjoerg       // Copy the aggregate.
6787330f729Sjoerg       CGF.EmitAggregateCopy(LHS, Src, FieldType, CGF.getOverlapForFieldInit(Field),
6797330f729Sjoerg                             LHS.isVolatileQualified());
6807330f729Sjoerg       // Ensure that we destroy the objects if an exception is thrown later in
6817330f729Sjoerg       // the constructor.
6827330f729Sjoerg       QualType::DestructionKind dtorKind = FieldType.isDestructedType();
6837330f729Sjoerg       if (CGF.needsEHCleanup(dtorKind))
684*e038c9c4Sjoerg         CGF.pushEHDestroy(dtorKind, LHS.getAddress(CGF), FieldType);
6857330f729Sjoerg       return;
6867330f729Sjoerg     }
6877330f729Sjoerg   }
6887330f729Sjoerg 
6897330f729Sjoerg   CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit());
6907330f729Sjoerg }
6917330f729Sjoerg 
EmitInitializerForField(FieldDecl * Field,LValue LHS,Expr * Init)6927330f729Sjoerg void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS,
6937330f729Sjoerg                                               Expr *Init) {
6947330f729Sjoerg   QualType FieldType = Field->getType();
6957330f729Sjoerg   switch (getEvaluationKind(FieldType)) {
6967330f729Sjoerg   case TEK_Scalar:
6977330f729Sjoerg     if (LHS.isSimple()) {
6987330f729Sjoerg       EmitExprAsInit(Init, Field, LHS, false);
6997330f729Sjoerg     } else {
7007330f729Sjoerg       RValue RHS = RValue::get(EmitScalarExpr(Init));
7017330f729Sjoerg       EmitStoreThroughLValue(RHS, LHS);
7027330f729Sjoerg     }
7037330f729Sjoerg     break;
7047330f729Sjoerg   case TEK_Complex:
7057330f729Sjoerg     EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true);
7067330f729Sjoerg     break;
7077330f729Sjoerg   case TEK_Aggregate: {
708*e038c9c4Sjoerg     AggValueSlot Slot = AggValueSlot::forLValue(
709*e038c9c4Sjoerg         LHS, *this, AggValueSlot::IsDestructed,
710*e038c9c4Sjoerg         AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased,
711*e038c9c4Sjoerg         getOverlapForFieldInit(Field), AggValueSlot::IsNotZeroed,
7127330f729Sjoerg         // Checks are made by the code that calls constructor.
7137330f729Sjoerg         AggValueSlot::IsSanitizerChecked);
7147330f729Sjoerg     EmitAggExpr(Init, Slot);
7157330f729Sjoerg     break;
7167330f729Sjoerg   }
7177330f729Sjoerg   }
7187330f729Sjoerg 
7197330f729Sjoerg   // Ensure that we destroy this object if an exception is thrown
7207330f729Sjoerg   // later in the constructor.
7217330f729Sjoerg   QualType::DestructionKind dtorKind = FieldType.isDestructedType();
7227330f729Sjoerg   if (needsEHCleanup(dtorKind))
723*e038c9c4Sjoerg     pushEHDestroy(dtorKind, LHS.getAddress(*this), FieldType);
7247330f729Sjoerg }
7257330f729Sjoerg 
7267330f729Sjoerg /// Checks whether the given constructor is a valid subject for the
7277330f729Sjoerg /// complete-to-base constructor delegation optimization, i.e.
7287330f729Sjoerg /// emitting the complete constructor as a simple call to the base
7297330f729Sjoerg /// constructor.
IsConstructorDelegationValid(const CXXConstructorDecl * Ctor)7307330f729Sjoerg bool CodeGenFunction::IsConstructorDelegationValid(
7317330f729Sjoerg     const CXXConstructorDecl *Ctor) {
7327330f729Sjoerg 
7337330f729Sjoerg   // Currently we disable the optimization for classes with virtual
7347330f729Sjoerg   // bases because (1) the addresses of parameter variables need to be
7357330f729Sjoerg   // consistent across all initializers but (2) the delegate function
7367330f729Sjoerg   // call necessarily creates a second copy of the parameter variable.
7377330f729Sjoerg   //
7387330f729Sjoerg   // The limiting example (purely theoretical AFAIK):
7397330f729Sjoerg   //   struct A { A(int &c) { c++; } };
7407330f729Sjoerg   //   struct B : virtual A {
7417330f729Sjoerg   //     B(int count) : A(count) { printf("%d\n", count); }
7427330f729Sjoerg   //   };
7437330f729Sjoerg   // ...although even this example could in principle be emitted as a
7447330f729Sjoerg   // delegation since the address of the parameter doesn't escape.
7457330f729Sjoerg   if (Ctor->getParent()->getNumVBases()) {
7467330f729Sjoerg     // TODO: white-list trivial vbase initializers.  This case wouldn't
7477330f729Sjoerg     // be subject to the restrictions below.
7487330f729Sjoerg 
7497330f729Sjoerg     // TODO: white-list cases where:
7507330f729Sjoerg     //  - there are no non-reference parameters to the constructor
7517330f729Sjoerg     //  - the initializers don't access any non-reference parameters
7527330f729Sjoerg     //  - the initializers don't take the address of non-reference
7537330f729Sjoerg     //    parameters
7547330f729Sjoerg     //  - etc.
7557330f729Sjoerg     // If we ever add any of the above cases, remember that:
756*e038c9c4Sjoerg     //  - function-try-blocks will always exclude this optimization
7577330f729Sjoerg     //  - we need to perform the constructor prologue and cleanup in
7587330f729Sjoerg     //    EmitConstructorBody.
7597330f729Sjoerg 
7607330f729Sjoerg     return false;
7617330f729Sjoerg   }
7627330f729Sjoerg 
7637330f729Sjoerg   // We also disable the optimization for variadic functions because
7647330f729Sjoerg   // it's impossible to "re-pass" varargs.
7657330f729Sjoerg   if (Ctor->getType()->castAs<FunctionProtoType>()->isVariadic())
7667330f729Sjoerg     return false;
7677330f729Sjoerg 
7687330f729Sjoerg   // FIXME: Decide if we can do a delegation of a delegating constructor.
7697330f729Sjoerg   if (Ctor->isDelegatingConstructor())
7707330f729Sjoerg     return false;
7717330f729Sjoerg 
7727330f729Sjoerg   return true;
7737330f729Sjoerg }
7747330f729Sjoerg 
7757330f729Sjoerg // Emit code in ctor (Prologue==true) or dtor (Prologue==false)
7767330f729Sjoerg // to poison the extra field paddings inserted under
7777330f729Sjoerg // -fsanitize-address-field-padding=1|2.
EmitAsanPrologueOrEpilogue(bool Prologue)7787330f729Sjoerg void CodeGenFunction::EmitAsanPrologueOrEpilogue(bool Prologue) {
7797330f729Sjoerg   ASTContext &Context = getContext();
7807330f729Sjoerg   const CXXRecordDecl *ClassDecl =
7817330f729Sjoerg       Prologue ? cast<CXXConstructorDecl>(CurGD.getDecl())->getParent()
7827330f729Sjoerg                : cast<CXXDestructorDecl>(CurGD.getDecl())->getParent();
7837330f729Sjoerg   if (!ClassDecl->mayInsertExtraPadding()) return;
7847330f729Sjoerg 
7857330f729Sjoerg   struct SizeAndOffset {
7867330f729Sjoerg     uint64_t Size;
7877330f729Sjoerg     uint64_t Offset;
7887330f729Sjoerg   };
7897330f729Sjoerg 
7907330f729Sjoerg   unsigned PtrSize = CGM.getDataLayout().getPointerSizeInBits();
7917330f729Sjoerg   const ASTRecordLayout &Info = Context.getASTRecordLayout(ClassDecl);
7927330f729Sjoerg 
7937330f729Sjoerg   // Populate sizes and offsets of fields.
7947330f729Sjoerg   SmallVector<SizeAndOffset, 16> SSV(Info.getFieldCount());
7957330f729Sjoerg   for (unsigned i = 0, e = Info.getFieldCount(); i != e; ++i)
7967330f729Sjoerg     SSV[i].Offset =
7977330f729Sjoerg         Context.toCharUnitsFromBits(Info.getFieldOffset(i)).getQuantity();
7987330f729Sjoerg 
7997330f729Sjoerg   size_t NumFields = 0;
8007330f729Sjoerg   for (const auto *Field : ClassDecl->fields()) {
8017330f729Sjoerg     const FieldDecl *D = Field;
802*e038c9c4Sjoerg     auto FieldInfo = Context.getTypeInfoInChars(D->getType());
803*e038c9c4Sjoerg     CharUnits FieldSize = FieldInfo.Width;
8047330f729Sjoerg     assert(NumFields < SSV.size());
8057330f729Sjoerg     SSV[NumFields].Size = D->isBitField() ? 0 : FieldSize.getQuantity();
8067330f729Sjoerg     NumFields++;
8077330f729Sjoerg   }
8087330f729Sjoerg   assert(NumFields == SSV.size());
8097330f729Sjoerg   if (SSV.size() <= 1) return;
8107330f729Sjoerg 
8117330f729Sjoerg   // We will insert calls to __asan_* run-time functions.
8127330f729Sjoerg   // LLVM AddressSanitizer pass may decide to inline them later.
8137330f729Sjoerg   llvm::Type *Args[2] = {IntPtrTy, IntPtrTy};
8147330f729Sjoerg   llvm::FunctionType *FTy =
8157330f729Sjoerg       llvm::FunctionType::get(CGM.VoidTy, Args, false);
8167330f729Sjoerg   llvm::FunctionCallee F = CGM.CreateRuntimeFunction(
8177330f729Sjoerg       FTy, Prologue ? "__asan_poison_intra_object_redzone"
8187330f729Sjoerg                     : "__asan_unpoison_intra_object_redzone");
8197330f729Sjoerg 
8207330f729Sjoerg   llvm::Value *ThisPtr = LoadCXXThis();
8217330f729Sjoerg   ThisPtr = Builder.CreatePtrToInt(ThisPtr, IntPtrTy);
8227330f729Sjoerg   uint64_t TypeSize = Info.getNonVirtualSize().getQuantity();
8237330f729Sjoerg   // For each field check if it has sufficient padding,
8247330f729Sjoerg   // if so (un)poison it with a call.
8257330f729Sjoerg   for (size_t i = 0; i < SSV.size(); i++) {
8267330f729Sjoerg     uint64_t AsanAlignment = 8;
8277330f729Sjoerg     uint64_t NextField = i == SSV.size() - 1 ? TypeSize : SSV[i + 1].Offset;
8287330f729Sjoerg     uint64_t PoisonSize = NextField - SSV[i].Offset - SSV[i].Size;
8297330f729Sjoerg     uint64_t EndOffset = SSV[i].Offset + SSV[i].Size;
8307330f729Sjoerg     if (PoisonSize < AsanAlignment || !SSV[i].Size ||
8317330f729Sjoerg         (NextField % AsanAlignment) != 0)
8327330f729Sjoerg       continue;
8337330f729Sjoerg     Builder.CreateCall(
8347330f729Sjoerg         F, {Builder.CreateAdd(ThisPtr, Builder.getIntN(PtrSize, EndOffset)),
8357330f729Sjoerg             Builder.getIntN(PtrSize, PoisonSize)});
8367330f729Sjoerg   }
8377330f729Sjoerg }
8387330f729Sjoerg 
8397330f729Sjoerg /// EmitConstructorBody - Emits the body of the current constructor.
EmitConstructorBody(FunctionArgList & Args)8407330f729Sjoerg void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) {
8417330f729Sjoerg   EmitAsanPrologueOrEpilogue(true);
8427330f729Sjoerg   const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl());
8437330f729Sjoerg   CXXCtorType CtorType = CurGD.getCtorType();
8447330f729Sjoerg 
8457330f729Sjoerg   assert((CGM.getTarget().getCXXABI().hasConstructorVariants() ||
8467330f729Sjoerg           CtorType == Ctor_Complete) &&
8477330f729Sjoerg          "can only generate complete ctor for this ABI");
8487330f729Sjoerg 
8497330f729Sjoerg   // Before we go any further, try the complete->base constructor
8507330f729Sjoerg   // delegation optimization.
8517330f729Sjoerg   if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor) &&
8527330f729Sjoerg       CGM.getTarget().getCXXABI().hasConstructorVariants()) {
8537330f729Sjoerg     EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args, Ctor->getEndLoc());
8547330f729Sjoerg     return;
8557330f729Sjoerg   }
8567330f729Sjoerg 
8577330f729Sjoerg   const FunctionDecl *Definition = nullptr;
8587330f729Sjoerg   Stmt *Body = Ctor->getBody(Definition);
8597330f729Sjoerg   assert(Definition == Ctor && "emitting wrong constructor body");
8607330f729Sjoerg 
8617330f729Sjoerg   // Enter the function-try-block before the constructor prologue if
8627330f729Sjoerg   // applicable.
8637330f729Sjoerg   bool IsTryBody = (Body && isa<CXXTryStmt>(Body));
8647330f729Sjoerg   if (IsTryBody)
8657330f729Sjoerg     EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true);
8667330f729Sjoerg 
8677330f729Sjoerg   incrementProfileCounter(Body);
8687330f729Sjoerg 
8697330f729Sjoerg   RunCleanupsScope RunCleanups(*this);
8707330f729Sjoerg 
8717330f729Sjoerg   // TODO: in restricted cases, we can emit the vbase initializers of
8727330f729Sjoerg   // a complete ctor and then delegate to the base ctor.
8737330f729Sjoerg 
8747330f729Sjoerg   // Emit the constructor prologue, i.e. the base and member
8757330f729Sjoerg   // initializers.
8767330f729Sjoerg   EmitCtorPrologue(Ctor, CtorType, Args);
8777330f729Sjoerg 
8787330f729Sjoerg   // Emit the body of the statement.
8797330f729Sjoerg   if (IsTryBody)
8807330f729Sjoerg     EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
8817330f729Sjoerg   else if (Body)
8827330f729Sjoerg     EmitStmt(Body);
8837330f729Sjoerg 
8847330f729Sjoerg   // Emit any cleanup blocks associated with the member or base
8857330f729Sjoerg   // initializers, which includes (along the exceptional path) the
8867330f729Sjoerg   // destructors for those members and bases that were fully
8877330f729Sjoerg   // constructed.
8887330f729Sjoerg   RunCleanups.ForceCleanup();
8897330f729Sjoerg 
8907330f729Sjoerg   if (IsTryBody)
8917330f729Sjoerg     ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);
8927330f729Sjoerg }
8937330f729Sjoerg 
8947330f729Sjoerg namespace {
8957330f729Sjoerg   /// RAII object to indicate that codegen is copying the value representation
8967330f729Sjoerg   /// instead of the object representation. Useful when copying a struct or
8977330f729Sjoerg   /// class which has uninitialized members and we're only performing
8987330f729Sjoerg   /// lvalue-to-rvalue conversion on the object but not its members.
8997330f729Sjoerg   class CopyingValueRepresentation {
9007330f729Sjoerg   public:
CopyingValueRepresentation(CodeGenFunction & CGF)9017330f729Sjoerg     explicit CopyingValueRepresentation(CodeGenFunction &CGF)
9027330f729Sjoerg         : CGF(CGF), OldSanOpts(CGF.SanOpts) {
9037330f729Sjoerg       CGF.SanOpts.set(SanitizerKind::Bool, false);
9047330f729Sjoerg       CGF.SanOpts.set(SanitizerKind::Enum, false);
9057330f729Sjoerg     }
~CopyingValueRepresentation()9067330f729Sjoerg     ~CopyingValueRepresentation() {
9077330f729Sjoerg       CGF.SanOpts = OldSanOpts;
9087330f729Sjoerg     }
9097330f729Sjoerg   private:
9107330f729Sjoerg     CodeGenFunction &CGF;
9117330f729Sjoerg     SanitizerSet OldSanOpts;
9127330f729Sjoerg   };
9137330f729Sjoerg } // end anonymous namespace
9147330f729Sjoerg 
9157330f729Sjoerg namespace {
9167330f729Sjoerg   class FieldMemcpyizer {
9177330f729Sjoerg   public:
FieldMemcpyizer(CodeGenFunction & CGF,const CXXRecordDecl * ClassDecl,const VarDecl * SrcRec)9187330f729Sjoerg     FieldMemcpyizer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl,
9197330f729Sjoerg                     const VarDecl *SrcRec)
9207330f729Sjoerg       : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec),
9217330f729Sjoerg         RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)),
9227330f729Sjoerg         FirstField(nullptr), LastField(nullptr), FirstFieldOffset(0),
9237330f729Sjoerg         LastFieldOffset(0), LastAddedFieldIndex(0) {}
9247330f729Sjoerg 
isMemcpyableField(FieldDecl * F) const9257330f729Sjoerg     bool isMemcpyableField(FieldDecl *F) const {
9267330f729Sjoerg       // Never memcpy fields when we are adding poisoned paddings.
9277330f729Sjoerg       if (CGF.getContext().getLangOpts().SanitizeAddressFieldPadding)
9287330f729Sjoerg         return false;
9297330f729Sjoerg       Qualifiers Qual = F->getType().getQualifiers();
9307330f729Sjoerg       if (Qual.hasVolatile() || Qual.hasObjCLifetime())
9317330f729Sjoerg         return false;
9327330f729Sjoerg       return true;
9337330f729Sjoerg     }
9347330f729Sjoerg 
addMemcpyableField(FieldDecl * F)9357330f729Sjoerg     void addMemcpyableField(FieldDecl *F) {
936*e038c9c4Sjoerg       if (F->isZeroSize(CGF.getContext()))
937*e038c9c4Sjoerg         return;
9387330f729Sjoerg       if (!FirstField)
9397330f729Sjoerg         addInitialField(F);
9407330f729Sjoerg       else
9417330f729Sjoerg         addNextField(F);
9427330f729Sjoerg     }
9437330f729Sjoerg 
getMemcpySize(uint64_t FirstByteOffset) const9447330f729Sjoerg     CharUnits getMemcpySize(uint64_t FirstByteOffset) const {
9457330f729Sjoerg       ASTContext &Ctx = CGF.getContext();
9467330f729Sjoerg       unsigned LastFieldSize =
9477330f729Sjoerg           LastField->isBitField()
9487330f729Sjoerg               ? LastField->getBitWidthValue(Ctx)
9497330f729Sjoerg               : Ctx.toBits(
950*e038c9c4Sjoerg                     Ctx.getTypeInfoDataSizeInChars(LastField->getType()).Width);
9517330f729Sjoerg       uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize -
9527330f729Sjoerg                                 FirstByteOffset + Ctx.getCharWidth() - 1;
9537330f729Sjoerg       CharUnits MemcpySize = Ctx.toCharUnitsFromBits(MemcpySizeBits);
9547330f729Sjoerg       return MemcpySize;
9557330f729Sjoerg     }
9567330f729Sjoerg 
emitMemcpy()9577330f729Sjoerg     void emitMemcpy() {
9587330f729Sjoerg       // Give the subclass a chance to bail out if it feels the memcpy isn't
9597330f729Sjoerg       // worth it (e.g. Hasn't aggregated enough data).
9607330f729Sjoerg       if (!FirstField) {
9617330f729Sjoerg         return;
9627330f729Sjoerg       }
9637330f729Sjoerg 
9647330f729Sjoerg       uint64_t FirstByteOffset;
9657330f729Sjoerg       if (FirstField->isBitField()) {
9667330f729Sjoerg         const CGRecordLayout &RL =
9677330f729Sjoerg           CGF.getTypes().getCGRecordLayout(FirstField->getParent());
9687330f729Sjoerg         const CGBitFieldInfo &BFInfo = RL.getBitFieldInfo(FirstField);
9697330f729Sjoerg         // FirstFieldOffset is not appropriate for bitfields,
9707330f729Sjoerg         // we need to use the storage offset instead.
9717330f729Sjoerg         FirstByteOffset = CGF.getContext().toBits(BFInfo.StorageOffset);
9727330f729Sjoerg       } else {
9737330f729Sjoerg         FirstByteOffset = FirstFieldOffset;
9747330f729Sjoerg       }
9757330f729Sjoerg 
9767330f729Sjoerg       CharUnits MemcpySize = getMemcpySize(FirstByteOffset);
9777330f729Sjoerg       QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
9787330f729Sjoerg       Address ThisPtr = CGF.LoadCXXThisAddress();
9797330f729Sjoerg       LValue DestLV = CGF.MakeAddrLValue(ThisPtr, RecordTy);
9807330f729Sjoerg       LValue Dest = CGF.EmitLValueForFieldInitialization(DestLV, FirstField);
9817330f729Sjoerg       llvm::Value *SrcPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(SrcRec));
9827330f729Sjoerg       LValue SrcLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy);
9837330f729Sjoerg       LValue Src = CGF.EmitLValueForFieldInitialization(SrcLV, FirstField);
9847330f729Sjoerg 
985*e038c9c4Sjoerg       emitMemcpyIR(
986*e038c9c4Sjoerg           Dest.isBitField() ? Dest.getBitFieldAddress() : Dest.getAddress(CGF),
987*e038c9c4Sjoerg           Src.isBitField() ? Src.getBitFieldAddress() : Src.getAddress(CGF),
9887330f729Sjoerg           MemcpySize);
9897330f729Sjoerg       reset();
9907330f729Sjoerg     }
9917330f729Sjoerg 
reset()9927330f729Sjoerg     void reset() {
9937330f729Sjoerg       FirstField = nullptr;
9947330f729Sjoerg     }
9957330f729Sjoerg 
9967330f729Sjoerg   protected:
9977330f729Sjoerg     CodeGenFunction &CGF;
9987330f729Sjoerg     const CXXRecordDecl *ClassDecl;
9997330f729Sjoerg 
10007330f729Sjoerg   private:
emitMemcpyIR(Address DestPtr,Address SrcPtr,CharUnits Size)10017330f729Sjoerg     void emitMemcpyIR(Address DestPtr, Address SrcPtr, CharUnits Size) {
10027330f729Sjoerg       llvm::PointerType *DPT = DestPtr.getType();
10037330f729Sjoerg       llvm::Type *DBP =
10047330f729Sjoerg         llvm::Type::getInt8PtrTy(CGF.getLLVMContext(), DPT->getAddressSpace());
10057330f729Sjoerg       DestPtr = CGF.Builder.CreateBitCast(DestPtr, DBP);
10067330f729Sjoerg 
10077330f729Sjoerg       llvm::PointerType *SPT = SrcPtr.getType();
10087330f729Sjoerg       llvm::Type *SBP =
10097330f729Sjoerg         llvm::Type::getInt8PtrTy(CGF.getLLVMContext(), SPT->getAddressSpace());
10107330f729Sjoerg       SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, SBP);
10117330f729Sjoerg 
10127330f729Sjoerg       CGF.Builder.CreateMemCpy(DestPtr, SrcPtr, Size.getQuantity());
10137330f729Sjoerg     }
10147330f729Sjoerg 
addInitialField(FieldDecl * F)10157330f729Sjoerg     void addInitialField(FieldDecl *F) {
10167330f729Sjoerg       FirstField = F;
10177330f729Sjoerg       LastField = F;
10187330f729Sjoerg       FirstFieldOffset = RecLayout.getFieldOffset(F->getFieldIndex());
10197330f729Sjoerg       LastFieldOffset = FirstFieldOffset;
10207330f729Sjoerg       LastAddedFieldIndex = F->getFieldIndex();
10217330f729Sjoerg     }
10227330f729Sjoerg 
addNextField(FieldDecl * F)10237330f729Sjoerg     void addNextField(FieldDecl *F) {
10247330f729Sjoerg       // For the most part, the following invariant will hold:
10257330f729Sjoerg       //   F->getFieldIndex() == LastAddedFieldIndex + 1
10267330f729Sjoerg       // The one exception is that Sema won't add a copy-initializer for an
10277330f729Sjoerg       // unnamed bitfield, which will show up here as a gap in the sequence.
10287330f729Sjoerg       assert(F->getFieldIndex() >= LastAddedFieldIndex + 1 &&
10297330f729Sjoerg              "Cannot aggregate fields out of order.");
10307330f729Sjoerg       LastAddedFieldIndex = F->getFieldIndex();
10317330f729Sjoerg 
10327330f729Sjoerg       // The 'first' and 'last' fields are chosen by offset, rather than field
10337330f729Sjoerg       // index. This allows the code to support bitfields, as well as regular
10347330f729Sjoerg       // fields.
10357330f729Sjoerg       uint64_t FOffset = RecLayout.getFieldOffset(F->getFieldIndex());
10367330f729Sjoerg       if (FOffset < FirstFieldOffset) {
10377330f729Sjoerg         FirstField = F;
10387330f729Sjoerg         FirstFieldOffset = FOffset;
10397330f729Sjoerg       } else if (FOffset >= LastFieldOffset) {
10407330f729Sjoerg         LastField = F;
10417330f729Sjoerg         LastFieldOffset = FOffset;
10427330f729Sjoerg       }
10437330f729Sjoerg     }
10447330f729Sjoerg 
10457330f729Sjoerg     const VarDecl *SrcRec;
10467330f729Sjoerg     const ASTRecordLayout &RecLayout;
10477330f729Sjoerg     FieldDecl *FirstField;
10487330f729Sjoerg     FieldDecl *LastField;
10497330f729Sjoerg     uint64_t FirstFieldOffset, LastFieldOffset;
10507330f729Sjoerg     unsigned LastAddedFieldIndex;
10517330f729Sjoerg   };
10527330f729Sjoerg 
10537330f729Sjoerg   class ConstructorMemcpyizer : public FieldMemcpyizer {
10547330f729Sjoerg   private:
10557330f729Sjoerg     /// Get source argument for copy constructor. Returns null if not a copy
10567330f729Sjoerg     /// constructor.
getTrivialCopySource(CodeGenFunction & CGF,const CXXConstructorDecl * CD,FunctionArgList & Args)10577330f729Sjoerg     static const VarDecl *getTrivialCopySource(CodeGenFunction &CGF,
10587330f729Sjoerg                                                const CXXConstructorDecl *CD,
10597330f729Sjoerg                                                FunctionArgList &Args) {
10607330f729Sjoerg       if (CD->isCopyOrMoveConstructor() && CD->isDefaulted())
10617330f729Sjoerg         return Args[CGF.CGM.getCXXABI().getSrcArgforCopyCtor(CD, Args)];
10627330f729Sjoerg       return nullptr;
10637330f729Sjoerg     }
10647330f729Sjoerg 
10657330f729Sjoerg     // Returns true if a CXXCtorInitializer represents a member initialization
10667330f729Sjoerg     // that can be rolled into a memcpy.
isMemberInitMemcpyable(CXXCtorInitializer * MemberInit) const10677330f729Sjoerg     bool isMemberInitMemcpyable(CXXCtorInitializer *MemberInit) const {
10687330f729Sjoerg       if (!MemcpyableCtor)
10697330f729Sjoerg         return false;
10707330f729Sjoerg       FieldDecl *Field = MemberInit->getMember();
10717330f729Sjoerg       assert(Field && "No field for member init.");
10727330f729Sjoerg       QualType FieldType = Field->getType();
10737330f729Sjoerg       CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit());
10747330f729Sjoerg 
10757330f729Sjoerg       // Bail out on non-memcpyable, not-trivially-copyable members.
10767330f729Sjoerg       if (!(CE && isMemcpyEquivalentSpecialMember(CE->getConstructor())) &&
10777330f729Sjoerg           !(FieldType.isTriviallyCopyableType(CGF.getContext()) ||
10787330f729Sjoerg             FieldType->isReferenceType()))
10797330f729Sjoerg         return false;
10807330f729Sjoerg 
10817330f729Sjoerg       // Bail out on volatile fields.
10827330f729Sjoerg       if (!isMemcpyableField(Field))
10837330f729Sjoerg         return false;
10847330f729Sjoerg 
10857330f729Sjoerg       // Otherwise we're good.
10867330f729Sjoerg       return true;
10877330f729Sjoerg     }
10887330f729Sjoerg 
10897330f729Sjoerg   public:
ConstructorMemcpyizer(CodeGenFunction & CGF,const CXXConstructorDecl * CD,FunctionArgList & Args)10907330f729Sjoerg     ConstructorMemcpyizer(CodeGenFunction &CGF, const CXXConstructorDecl *CD,
10917330f729Sjoerg                           FunctionArgList &Args)
10927330f729Sjoerg       : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CGF, CD, Args)),
10937330f729Sjoerg         ConstructorDecl(CD),
10947330f729Sjoerg         MemcpyableCtor(CD->isDefaulted() &&
10957330f729Sjoerg                        CD->isCopyOrMoveConstructor() &&
10967330f729Sjoerg                        CGF.getLangOpts().getGC() == LangOptions::NonGC),
10977330f729Sjoerg         Args(Args) { }
10987330f729Sjoerg 
addMemberInitializer(CXXCtorInitializer * MemberInit)10997330f729Sjoerg     void addMemberInitializer(CXXCtorInitializer *MemberInit) {
11007330f729Sjoerg       if (isMemberInitMemcpyable(MemberInit)) {
11017330f729Sjoerg         AggregatedInits.push_back(MemberInit);
11027330f729Sjoerg         addMemcpyableField(MemberInit->getMember());
11037330f729Sjoerg       } else {
11047330f729Sjoerg         emitAggregatedInits();
11057330f729Sjoerg         EmitMemberInitializer(CGF, ConstructorDecl->getParent(), MemberInit,
11067330f729Sjoerg                               ConstructorDecl, Args);
11077330f729Sjoerg       }
11087330f729Sjoerg     }
11097330f729Sjoerg 
emitAggregatedInits()11107330f729Sjoerg     void emitAggregatedInits() {
11117330f729Sjoerg       if (AggregatedInits.size() <= 1) {
11127330f729Sjoerg         // This memcpy is too small to be worthwhile. Fall back on default
11137330f729Sjoerg         // codegen.
11147330f729Sjoerg         if (!AggregatedInits.empty()) {
11157330f729Sjoerg           CopyingValueRepresentation CVR(CGF);
11167330f729Sjoerg           EmitMemberInitializer(CGF, ConstructorDecl->getParent(),
11177330f729Sjoerg                                 AggregatedInits[0], ConstructorDecl, Args);
11187330f729Sjoerg           AggregatedInits.clear();
11197330f729Sjoerg         }
11207330f729Sjoerg         reset();
11217330f729Sjoerg         return;
11227330f729Sjoerg       }
11237330f729Sjoerg 
11247330f729Sjoerg       pushEHDestructors();
11257330f729Sjoerg       emitMemcpy();
11267330f729Sjoerg       AggregatedInits.clear();
11277330f729Sjoerg     }
11287330f729Sjoerg 
pushEHDestructors()11297330f729Sjoerg     void pushEHDestructors() {
11307330f729Sjoerg       Address ThisPtr = CGF.LoadCXXThisAddress();
11317330f729Sjoerg       QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
11327330f729Sjoerg       LValue LHS = CGF.MakeAddrLValue(ThisPtr, RecordTy);
11337330f729Sjoerg 
11347330f729Sjoerg       for (unsigned i = 0; i < AggregatedInits.size(); ++i) {
11357330f729Sjoerg         CXXCtorInitializer *MemberInit = AggregatedInits[i];
11367330f729Sjoerg         QualType FieldType = MemberInit->getAnyMember()->getType();
11377330f729Sjoerg         QualType::DestructionKind dtorKind = FieldType.isDestructedType();
11387330f729Sjoerg         if (!CGF.needsEHCleanup(dtorKind))
11397330f729Sjoerg           continue;
11407330f729Sjoerg         LValue FieldLHS = LHS;
11417330f729Sjoerg         EmitLValueForAnyFieldInitialization(CGF, MemberInit, FieldLHS);
1142*e038c9c4Sjoerg         CGF.pushEHDestroy(dtorKind, FieldLHS.getAddress(CGF), FieldType);
11437330f729Sjoerg       }
11447330f729Sjoerg     }
11457330f729Sjoerg 
finish()11467330f729Sjoerg     void finish() {
11477330f729Sjoerg       emitAggregatedInits();
11487330f729Sjoerg     }
11497330f729Sjoerg 
11507330f729Sjoerg   private:
11517330f729Sjoerg     const CXXConstructorDecl *ConstructorDecl;
11527330f729Sjoerg     bool MemcpyableCtor;
11537330f729Sjoerg     FunctionArgList &Args;
11547330f729Sjoerg     SmallVector<CXXCtorInitializer*, 16> AggregatedInits;
11557330f729Sjoerg   };
11567330f729Sjoerg 
11577330f729Sjoerg   class AssignmentMemcpyizer : public FieldMemcpyizer {
11587330f729Sjoerg   private:
11597330f729Sjoerg     // Returns the memcpyable field copied by the given statement, if one
11607330f729Sjoerg     // exists. Otherwise returns null.
getMemcpyableField(Stmt * S)11617330f729Sjoerg     FieldDecl *getMemcpyableField(Stmt *S) {
11627330f729Sjoerg       if (!AssignmentsMemcpyable)
11637330f729Sjoerg         return nullptr;
11647330f729Sjoerg       if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) {
11657330f729Sjoerg         // Recognise trivial assignments.
11667330f729Sjoerg         if (BO->getOpcode() != BO_Assign)
11677330f729Sjoerg           return nullptr;
11687330f729Sjoerg         MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS());
11697330f729Sjoerg         if (!ME)
11707330f729Sjoerg           return nullptr;
11717330f729Sjoerg         FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl());
11727330f729Sjoerg         if (!Field || !isMemcpyableField(Field))
11737330f729Sjoerg           return nullptr;
11747330f729Sjoerg         Stmt *RHS = BO->getRHS();
11757330f729Sjoerg         if (ImplicitCastExpr *EC = dyn_cast<ImplicitCastExpr>(RHS))
11767330f729Sjoerg           RHS = EC->getSubExpr();
11777330f729Sjoerg         if (!RHS)
11787330f729Sjoerg           return nullptr;
11797330f729Sjoerg         if (MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) {
11807330f729Sjoerg           if (ME2->getMemberDecl() == Field)
11817330f729Sjoerg             return Field;
11827330f729Sjoerg         }
11837330f729Sjoerg         return nullptr;
11847330f729Sjoerg       } else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) {
11857330f729Sjoerg         CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl());
11867330f729Sjoerg         if (!(MD && isMemcpyEquivalentSpecialMember(MD)))
11877330f729Sjoerg           return nullptr;
11887330f729Sjoerg         MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument());
11897330f729Sjoerg         if (!IOA)
11907330f729Sjoerg           return nullptr;
11917330f729Sjoerg         FieldDecl *Field = dyn_cast<FieldDecl>(IOA->getMemberDecl());
11927330f729Sjoerg         if (!Field || !isMemcpyableField(Field))
11937330f729Sjoerg           return nullptr;
11947330f729Sjoerg         MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0));
11957330f729Sjoerg         if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->getMemberDecl()))
11967330f729Sjoerg           return nullptr;
11977330f729Sjoerg         return Field;
11987330f729Sjoerg       } else if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
11997330f729Sjoerg         FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
12007330f729Sjoerg         if (!FD || FD->getBuiltinID() != Builtin::BI__builtin_memcpy)
12017330f729Sjoerg           return nullptr;
12027330f729Sjoerg         Expr *DstPtr = CE->getArg(0);
12037330f729Sjoerg         if (ImplicitCastExpr *DC = dyn_cast<ImplicitCastExpr>(DstPtr))
12047330f729Sjoerg           DstPtr = DC->getSubExpr();
12057330f729Sjoerg         UnaryOperator *DUO = dyn_cast<UnaryOperator>(DstPtr);
12067330f729Sjoerg         if (!DUO || DUO->getOpcode() != UO_AddrOf)
12077330f729Sjoerg           return nullptr;
12087330f729Sjoerg         MemberExpr *ME = dyn_cast<MemberExpr>(DUO->getSubExpr());
12097330f729Sjoerg         if (!ME)
12107330f729Sjoerg           return nullptr;
12117330f729Sjoerg         FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl());
12127330f729Sjoerg         if (!Field || !isMemcpyableField(Field))
12137330f729Sjoerg           return nullptr;
12147330f729Sjoerg         Expr *SrcPtr = CE->getArg(1);
12157330f729Sjoerg         if (ImplicitCastExpr *SC = dyn_cast<ImplicitCastExpr>(SrcPtr))
12167330f729Sjoerg           SrcPtr = SC->getSubExpr();
12177330f729Sjoerg         UnaryOperator *SUO = dyn_cast<UnaryOperator>(SrcPtr);
12187330f729Sjoerg         if (!SUO || SUO->getOpcode() != UO_AddrOf)
12197330f729Sjoerg           return nullptr;
12207330f729Sjoerg         MemberExpr *ME2 = dyn_cast<MemberExpr>(SUO->getSubExpr());
12217330f729Sjoerg         if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->getMemberDecl()))
12227330f729Sjoerg           return nullptr;
12237330f729Sjoerg         return Field;
12247330f729Sjoerg       }
12257330f729Sjoerg 
12267330f729Sjoerg       return nullptr;
12277330f729Sjoerg     }
12287330f729Sjoerg 
12297330f729Sjoerg     bool AssignmentsMemcpyable;
12307330f729Sjoerg     SmallVector<Stmt*, 16> AggregatedStmts;
12317330f729Sjoerg 
12327330f729Sjoerg   public:
AssignmentMemcpyizer(CodeGenFunction & CGF,const CXXMethodDecl * AD,FunctionArgList & Args)12337330f729Sjoerg     AssignmentMemcpyizer(CodeGenFunction &CGF, const CXXMethodDecl *AD,
12347330f729Sjoerg                          FunctionArgList &Args)
12357330f729Sjoerg       : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]),
12367330f729Sjoerg         AssignmentsMemcpyable(CGF.getLangOpts().getGC() == LangOptions::NonGC) {
12377330f729Sjoerg       assert(Args.size() == 2);
12387330f729Sjoerg     }
12397330f729Sjoerg 
emitAssignment(Stmt * S)12407330f729Sjoerg     void emitAssignment(Stmt *S) {
12417330f729Sjoerg       FieldDecl *F = getMemcpyableField(S);
12427330f729Sjoerg       if (F) {
12437330f729Sjoerg         addMemcpyableField(F);
12447330f729Sjoerg         AggregatedStmts.push_back(S);
12457330f729Sjoerg       } else {
12467330f729Sjoerg         emitAggregatedStmts();
12477330f729Sjoerg         CGF.EmitStmt(S);
12487330f729Sjoerg       }
12497330f729Sjoerg     }
12507330f729Sjoerg 
emitAggregatedStmts()12517330f729Sjoerg     void emitAggregatedStmts() {
12527330f729Sjoerg       if (AggregatedStmts.size() <= 1) {
12537330f729Sjoerg         if (!AggregatedStmts.empty()) {
12547330f729Sjoerg           CopyingValueRepresentation CVR(CGF);
12557330f729Sjoerg           CGF.EmitStmt(AggregatedStmts[0]);
12567330f729Sjoerg         }
12577330f729Sjoerg         reset();
12587330f729Sjoerg       }
12597330f729Sjoerg 
12607330f729Sjoerg       emitMemcpy();
12617330f729Sjoerg       AggregatedStmts.clear();
12627330f729Sjoerg     }
12637330f729Sjoerg 
finish()12647330f729Sjoerg     void finish() {
12657330f729Sjoerg       emitAggregatedStmts();
12667330f729Sjoerg     }
12677330f729Sjoerg   };
12687330f729Sjoerg } // end anonymous namespace
12697330f729Sjoerg 
isInitializerOfDynamicClass(const CXXCtorInitializer * BaseInit)12707330f729Sjoerg static bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit) {
12717330f729Sjoerg   const Type *BaseType = BaseInit->getBaseClass();
12727330f729Sjoerg   const auto *BaseClassDecl =
12737330f729Sjoerg       cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl());
12747330f729Sjoerg   return BaseClassDecl->isDynamicClass();
12757330f729Sjoerg }
12767330f729Sjoerg 
12777330f729Sjoerg /// EmitCtorPrologue - This routine generates necessary code to initialize
12787330f729Sjoerg /// base classes and non-static data members belonging to this constructor.
EmitCtorPrologue(const CXXConstructorDecl * CD,CXXCtorType CtorType,FunctionArgList & Args)12797330f729Sjoerg void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
12807330f729Sjoerg                                        CXXCtorType CtorType,
12817330f729Sjoerg                                        FunctionArgList &Args) {
12827330f729Sjoerg   if (CD->isDelegatingConstructor())
12837330f729Sjoerg     return EmitDelegatingCXXConstructorCall(CD, Args);
12847330f729Sjoerg 
12857330f729Sjoerg   const CXXRecordDecl *ClassDecl = CD->getParent();
12867330f729Sjoerg 
12877330f729Sjoerg   CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
12887330f729Sjoerg                                           E = CD->init_end();
12897330f729Sjoerg 
12907330f729Sjoerg   // Virtual base initializers first, if any. They aren't needed if:
12917330f729Sjoerg   // - This is a base ctor variant
12927330f729Sjoerg   // - There are no vbases
12937330f729Sjoerg   // - The class is abstract, so a complete object of it cannot be constructed
12947330f729Sjoerg   //
12957330f729Sjoerg   // The check for an abstract class is necessary because sema may not have
12967330f729Sjoerg   // marked virtual base destructors referenced.
12977330f729Sjoerg   bool ConstructVBases = CtorType != Ctor_Base &&
12987330f729Sjoerg                          ClassDecl->getNumVBases() != 0 &&
12997330f729Sjoerg                          !ClassDecl->isAbstract();
13007330f729Sjoerg 
13017330f729Sjoerg   // In the Microsoft C++ ABI, there are no constructor variants. Instead, the
13027330f729Sjoerg   // constructor of a class with virtual bases takes an additional parameter to
13037330f729Sjoerg   // conditionally construct the virtual bases. Emit that check here.
13047330f729Sjoerg   llvm::BasicBlock *BaseCtorContinueBB = nullptr;
13057330f729Sjoerg   if (ConstructVBases &&
13067330f729Sjoerg       !CGM.getTarget().getCXXABI().hasConstructorVariants()) {
13077330f729Sjoerg     BaseCtorContinueBB =
13087330f729Sjoerg         CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this, ClassDecl);
13097330f729Sjoerg     assert(BaseCtorContinueBB);
13107330f729Sjoerg   }
13117330f729Sjoerg 
13127330f729Sjoerg   llvm::Value *const OldThis = CXXThisValue;
13137330f729Sjoerg   for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
13147330f729Sjoerg     if (!ConstructVBases)
13157330f729Sjoerg       continue;
13167330f729Sjoerg     if (CGM.getCodeGenOpts().StrictVTablePointers &&
13177330f729Sjoerg         CGM.getCodeGenOpts().OptimizationLevel > 0 &&
13187330f729Sjoerg         isInitializerOfDynamicClass(*B))
13197330f729Sjoerg       CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
13207330f729Sjoerg     EmitBaseInitializer(*this, ClassDecl, *B);
13217330f729Sjoerg   }
13227330f729Sjoerg 
13237330f729Sjoerg   if (BaseCtorContinueBB) {
13247330f729Sjoerg     // Complete object handler should continue to the remaining initializers.
13257330f729Sjoerg     Builder.CreateBr(BaseCtorContinueBB);
13267330f729Sjoerg     EmitBlock(BaseCtorContinueBB);
13277330f729Sjoerg   }
13287330f729Sjoerg 
13297330f729Sjoerg   // Then, non-virtual base initializers.
13307330f729Sjoerg   for (; B != E && (*B)->isBaseInitializer(); B++) {
13317330f729Sjoerg     assert(!(*B)->isBaseVirtual());
13327330f729Sjoerg 
13337330f729Sjoerg     if (CGM.getCodeGenOpts().StrictVTablePointers &&
13347330f729Sjoerg         CGM.getCodeGenOpts().OptimizationLevel > 0 &&
13357330f729Sjoerg         isInitializerOfDynamicClass(*B))
13367330f729Sjoerg       CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
13377330f729Sjoerg     EmitBaseInitializer(*this, ClassDecl, *B);
13387330f729Sjoerg   }
13397330f729Sjoerg 
13407330f729Sjoerg   CXXThisValue = OldThis;
13417330f729Sjoerg 
13427330f729Sjoerg   InitializeVTablePointers(ClassDecl);
13437330f729Sjoerg 
13447330f729Sjoerg   // And finally, initialize class members.
13457330f729Sjoerg   FieldConstructionScope FCS(*this, LoadCXXThisAddress());
13467330f729Sjoerg   ConstructorMemcpyizer CM(*this, CD, Args);
13477330f729Sjoerg   for (; B != E; B++) {
13487330f729Sjoerg     CXXCtorInitializer *Member = (*B);
13497330f729Sjoerg     assert(!Member->isBaseInitializer());
13507330f729Sjoerg     assert(Member->isAnyMemberInitializer() &&
13517330f729Sjoerg            "Delegating initializer on non-delegating constructor");
13527330f729Sjoerg     CM.addMemberInitializer(Member);
13537330f729Sjoerg   }
13547330f729Sjoerg   CM.finish();
13557330f729Sjoerg }
13567330f729Sjoerg 
13577330f729Sjoerg static bool
13587330f729Sjoerg FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
13597330f729Sjoerg 
13607330f729Sjoerg static bool
HasTrivialDestructorBody(ASTContext & Context,const CXXRecordDecl * BaseClassDecl,const CXXRecordDecl * MostDerivedClassDecl)13617330f729Sjoerg HasTrivialDestructorBody(ASTContext &Context,
13627330f729Sjoerg                          const CXXRecordDecl *BaseClassDecl,
13637330f729Sjoerg                          const CXXRecordDecl *MostDerivedClassDecl)
13647330f729Sjoerg {
13657330f729Sjoerg   // If the destructor is trivial we don't have to check anything else.
13667330f729Sjoerg   if (BaseClassDecl->hasTrivialDestructor())
13677330f729Sjoerg     return true;
13687330f729Sjoerg 
13697330f729Sjoerg   if (!BaseClassDecl->getDestructor()->hasTrivialBody())
13707330f729Sjoerg     return false;
13717330f729Sjoerg 
13727330f729Sjoerg   // Check fields.
13737330f729Sjoerg   for (const auto *Field : BaseClassDecl->fields())
13747330f729Sjoerg     if (!FieldHasTrivialDestructorBody(Context, Field))
13757330f729Sjoerg       return false;
13767330f729Sjoerg 
13777330f729Sjoerg   // Check non-virtual bases.
13787330f729Sjoerg   for (const auto &I : BaseClassDecl->bases()) {
13797330f729Sjoerg     if (I.isVirtual())
13807330f729Sjoerg       continue;
13817330f729Sjoerg 
13827330f729Sjoerg     const CXXRecordDecl *NonVirtualBase =
13837330f729Sjoerg       cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
13847330f729Sjoerg     if (!HasTrivialDestructorBody(Context, NonVirtualBase,
13857330f729Sjoerg                                   MostDerivedClassDecl))
13867330f729Sjoerg       return false;
13877330f729Sjoerg   }
13887330f729Sjoerg 
13897330f729Sjoerg   if (BaseClassDecl == MostDerivedClassDecl) {
13907330f729Sjoerg     // Check virtual bases.
13917330f729Sjoerg     for (const auto &I : BaseClassDecl->vbases()) {
13927330f729Sjoerg       const CXXRecordDecl *VirtualBase =
13937330f729Sjoerg         cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
13947330f729Sjoerg       if (!HasTrivialDestructorBody(Context, VirtualBase,
13957330f729Sjoerg                                     MostDerivedClassDecl))
13967330f729Sjoerg         return false;
13977330f729Sjoerg     }
13987330f729Sjoerg   }
13997330f729Sjoerg 
14007330f729Sjoerg   return true;
14017330f729Sjoerg }
14027330f729Sjoerg 
14037330f729Sjoerg static bool
FieldHasTrivialDestructorBody(ASTContext & Context,const FieldDecl * Field)14047330f729Sjoerg FieldHasTrivialDestructorBody(ASTContext &Context,
14057330f729Sjoerg                                           const FieldDecl *Field)
14067330f729Sjoerg {
14077330f729Sjoerg   QualType FieldBaseElementType = Context.getBaseElementType(Field->getType());
14087330f729Sjoerg 
14097330f729Sjoerg   const RecordType *RT = FieldBaseElementType->getAs<RecordType>();
14107330f729Sjoerg   if (!RT)
14117330f729Sjoerg     return true;
14127330f729Sjoerg 
14137330f729Sjoerg   CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
14147330f729Sjoerg 
14157330f729Sjoerg   // The destructor for an implicit anonymous union member is never invoked.
14167330f729Sjoerg   if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
14177330f729Sjoerg     return false;
14187330f729Sjoerg 
14197330f729Sjoerg   return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl);
14207330f729Sjoerg }
14217330f729Sjoerg 
14227330f729Sjoerg /// CanSkipVTablePointerInitialization - Check whether we need to initialize
14237330f729Sjoerg /// any vtable pointers before calling this destructor.
CanSkipVTablePointerInitialization(CodeGenFunction & CGF,const CXXDestructorDecl * Dtor)14247330f729Sjoerg static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF,
14257330f729Sjoerg                                                const CXXDestructorDecl *Dtor) {
14267330f729Sjoerg   const CXXRecordDecl *ClassDecl = Dtor->getParent();
14277330f729Sjoerg   if (!ClassDecl->isDynamicClass())
14287330f729Sjoerg     return true;
14297330f729Sjoerg 
14307330f729Sjoerg   if (!Dtor->hasTrivialBody())
14317330f729Sjoerg     return false;
14327330f729Sjoerg 
14337330f729Sjoerg   // Check the fields.
14347330f729Sjoerg   for (const auto *Field : ClassDecl->fields())
14357330f729Sjoerg     if (!FieldHasTrivialDestructorBody(CGF.getContext(), Field))
14367330f729Sjoerg       return false;
14377330f729Sjoerg 
14387330f729Sjoerg   return true;
14397330f729Sjoerg }
14407330f729Sjoerg 
14417330f729Sjoerg /// EmitDestructorBody - Emits the body of the current destructor.
EmitDestructorBody(FunctionArgList & Args)14427330f729Sjoerg void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
14437330f729Sjoerg   const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl());
14447330f729Sjoerg   CXXDtorType DtorType = CurGD.getDtorType();
14457330f729Sjoerg 
14467330f729Sjoerg   // For an abstract class, non-base destructors are never used (and can't
14477330f729Sjoerg   // be emitted in general, because vbase dtors may not have been validated
14487330f729Sjoerg   // by Sema), but the Itanium ABI doesn't make them optional and Clang may
14497330f729Sjoerg   // in fact emit references to them from other compilations, so emit them
14507330f729Sjoerg   // as functions containing a trap instruction.
14517330f729Sjoerg   if (DtorType != Dtor_Base && Dtor->getParent()->isAbstract()) {
14527330f729Sjoerg     llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
14537330f729Sjoerg     TrapCall->setDoesNotReturn();
14547330f729Sjoerg     TrapCall->setDoesNotThrow();
14557330f729Sjoerg     Builder.CreateUnreachable();
14567330f729Sjoerg     Builder.ClearInsertionPoint();
14577330f729Sjoerg     return;
14587330f729Sjoerg   }
14597330f729Sjoerg 
14607330f729Sjoerg   Stmt *Body = Dtor->getBody();
14617330f729Sjoerg   if (Body)
14627330f729Sjoerg     incrementProfileCounter(Body);
14637330f729Sjoerg 
14647330f729Sjoerg   // The call to operator delete in a deleting destructor happens
14657330f729Sjoerg   // outside of the function-try-block, which means it's always
14667330f729Sjoerg   // possible to delegate the destructor body to the complete
14677330f729Sjoerg   // destructor.  Do so.
14687330f729Sjoerg   if (DtorType == Dtor_Deleting) {
14697330f729Sjoerg     RunCleanupsScope DtorEpilogue(*this);
14707330f729Sjoerg     EnterDtorCleanups(Dtor, Dtor_Deleting);
14717330f729Sjoerg     if (HaveInsertPoint()) {
14727330f729Sjoerg       QualType ThisTy = Dtor->getThisObjectType();
14737330f729Sjoerg       EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
14747330f729Sjoerg                             /*Delegating=*/false, LoadCXXThisAddress(), ThisTy);
14757330f729Sjoerg     }
14767330f729Sjoerg     return;
14777330f729Sjoerg   }
14787330f729Sjoerg 
14797330f729Sjoerg   // If the body is a function-try-block, enter the try before
14807330f729Sjoerg   // anything else.
14817330f729Sjoerg   bool isTryBody = (Body && isa<CXXTryStmt>(Body));
14827330f729Sjoerg   if (isTryBody)
14837330f729Sjoerg     EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true);
14847330f729Sjoerg   EmitAsanPrologueOrEpilogue(false);
14857330f729Sjoerg 
14867330f729Sjoerg   // Enter the epilogue cleanups.
14877330f729Sjoerg   RunCleanupsScope DtorEpilogue(*this);
14887330f729Sjoerg 
14897330f729Sjoerg   // If this is the complete variant, just invoke the base variant;
14907330f729Sjoerg   // the epilogue will destruct the virtual bases.  But we can't do
14917330f729Sjoerg   // this optimization if the body is a function-try-block, because
14927330f729Sjoerg   // we'd introduce *two* handler blocks.  In the Microsoft ABI, we
14937330f729Sjoerg   // always delegate because we might not have a definition in this TU.
14947330f729Sjoerg   switch (DtorType) {
14957330f729Sjoerg   case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT");
14967330f729Sjoerg   case Dtor_Deleting: llvm_unreachable("already handled deleting case");
14977330f729Sjoerg 
14987330f729Sjoerg   case Dtor_Complete:
14997330f729Sjoerg     assert((Body || getTarget().getCXXABI().isMicrosoft()) &&
15007330f729Sjoerg            "can't emit a dtor without a body for non-Microsoft ABIs");
15017330f729Sjoerg 
15027330f729Sjoerg     // Enter the cleanup scopes for virtual bases.
15037330f729Sjoerg     EnterDtorCleanups(Dtor, Dtor_Complete);
15047330f729Sjoerg 
15057330f729Sjoerg     if (!isTryBody) {
15067330f729Sjoerg       QualType ThisTy = Dtor->getThisObjectType();
15077330f729Sjoerg       EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false,
15087330f729Sjoerg                             /*Delegating=*/false, LoadCXXThisAddress(), ThisTy);
15097330f729Sjoerg       break;
15107330f729Sjoerg     }
15117330f729Sjoerg 
15127330f729Sjoerg     // Fallthrough: act like we're in the base variant.
15137330f729Sjoerg     LLVM_FALLTHROUGH;
15147330f729Sjoerg 
15157330f729Sjoerg   case Dtor_Base:
15167330f729Sjoerg     assert(Body);
15177330f729Sjoerg 
15187330f729Sjoerg     // Enter the cleanup scopes for fields and non-virtual bases.
15197330f729Sjoerg     EnterDtorCleanups(Dtor, Dtor_Base);
15207330f729Sjoerg 
15217330f729Sjoerg     // Initialize the vtable pointers before entering the body.
15227330f729Sjoerg     if (!CanSkipVTablePointerInitialization(*this, Dtor)) {
15237330f729Sjoerg       // Insert the llvm.launder.invariant.group intrinsic before initializing
15247330f729Sjoerg       // the vptrs to cancel any previous assumptions we might have made.
15257330f729Sjoerg       if (CGM.getCodeGenOpts().StrictVTablePointers &&
15267330f729Sjoerg           CGM.getCodeGenOpts().OptimizationLevel > 0)
15277330f729Sjoerg         CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
15287330f729Sjoerg       InitializeVTablePointers(Dtor->getParent());
15297330f729Sjoerg     }
15307330f729Sjoerg 
15317330f729Sjoerg     if (isTryBody)
15327330f729Sjoerg       EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
15337330f729Sjoerg     else if (Body)
15347330f729Sjoerg       EmitStmt(Body);
15357330f729Sjoerg     else {
15367330f729Sjoerg       assert(Dtor->isImplicit() && "bodyless dtor not implicit");
15377330f729Sjoerg       // nothing to do besides what's in the epilogue
15387330f729Sjoerg     }
15397330f729Sjoerg     // -fapple-kext must inline any call to this dtor into
15407330f729Sjoerg     // the caller's body.
15417330f729Sjoerg     if (getLangOpts().AppleKext)
15427330f729Sjoerg       CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
15437330f729Sjoerg 
15447330f729Sjoerg     break;
15457330f729Sjoerg   }
15467330f729Sjoerg 
15477330f729Sjoerg   // Jump out through the epilogue cleanups.
15487330f729Sjoerg   DtorEpilogue.ForceCleanup();
15497330f729Sjoerg 
15507330f729Sjoerg   // Exit the try if applicable.
15517330f729Sjoerg   if (isTryBody)
15527330f729Sjoerg     ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);
15537330f729Sjoerg }
15547330f729Sjoerg 
emitImplicitAssignmentOperatorBody(FunctionArgList & Args)15557330f729Sjoerg void CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args) {
15567330f729Sjoerg   const CXXMethodDecl *AssignOp = cast<CXXMethodDecl>(CurGD.getDecl());
15577330f729Sjoerg   const Stmt *RootS = AssignOp->getBody();
15587330f729Sjoerg   assert(isa<CompoundStmt>(RootS) &&
15597330f729Sjoerg          "Body of an implicit assignment operator should be compound stmt.");
15607330f729Sjoerg   const CompoundStmt *RootCS = cast<CompoundStmt>(RootS);
15617330f729Sjoerg 
15627330f729Sjoerg   LexicalScope Scope(*this, RootCS->getSourceRange());
15637330f729Sjoerg 
15647330f729Sjoerg   incrementProfileCounter(RootCS);
15657330f729Sjoerg   AssignmentMemcpyizer AM(*this, AssignOp, Args);
15667330f729Sjoerg   for (auto *I : RootCS->body())
15677330f729Sjoerg     AM.emitAssignment(I);
15687330f729Sjoerg   AM.finish();
15697330f729Sjoerg }
15707330f729Sjoerg 
15717330f729Sjoerg namespace {
LoadThisForDtorDelete(CodeGenFunction & CGF,const CXXDestructorDecl * DD)15727330f729Sjoerg   llvm::Value *LoadThisForDtorDelete(CodeGenFunction &CGF,
15737330f729Sjoerg                                      const CXXDestructorDecl *DD) {
15747330f729Sjoerg     if (Expr *ThisArg = DD->getOperatorDeleteThisArg())
15757330f729Sjoerg       return CGF.EmitScalarExpr(ThisArg);
15767330f729Sjoerg     return CGF.LoadCXXThis();
15777330f729Sjoerg   }
15787330f729Sjoerg 
15797330f729Sjoerg   /// Call the operator delete associated with the current destructor.
15807330f729Sjoerg   struct CallDtorDelete final : EHScopeStack::Cleanup {
CallDtorDelete__anonb72786c90411::CallDtorDelete15817330f729Sjoerg     CallDtorDelete() {}
15827330f729Sjoerg 
Emit__anonb72786c90411::CallDtorDelete15837330f729Sjoerg     void Emit(CodeGenFunction &CGF, Flags flags) override {
15847330f729Sjoerg       const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl);
15857330f729Sjoerg       const CXXRecordDecl *ClassDecl = Dtor->getParent();
15867330f729Sjoerg       CGF.EmitDeleteCall(Dtor->getOperatorDelete(),
15877330f729Sjoerg                          LoadThisForDtorDelete(CGF, Dtor),
15887330f729Sjoerg                          CGF.getContext().getTagDeclType(ClassDecl));
15897330f729Sjoerg     }
15907330f729Sjoerg   };
15917330f729Sjoerg 
EmitConditionalDtorDeleteCall(CodeGenFunction & CGF,llvm::Value * ShouldDeleteCondition,bool ReturnAfterDelete)15927330f729Sjoerg   void EmitConditionalDtorDeleteCall(CodeGenFunction &CGF,
15937330f729Sjoerg                                      llvm::Value *ShouldDeleteCondition,
15947330f729Sjoerg                                      bool ReturnAfterDelete) {
15957330f729Sjoerg     llvm::BasicBlock *callDeleteBB = CGF.createBasicBlock("dtor.call_delete");
15967330f729Sjoerg     llvm::BasicBlock *continueBB = CGF.createBasicBlock("dtor.continue");
15977330f729Sjoerg     llvm::Value *ShouldCallDelete
15987330f729Sjoerg       = CGF.Builder.CreateIsNull(ShouldDeleteCondition);
15997330f729Sjoerg     CGF.Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
16007330f729Sjoerg 
16017330f729Sjoerg     CGF.EmitBlock(callDeleteBB);
16027330f729Sjoerg     const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl);
16037330f729Sjoerg     const CXXRecordDecl *ClassDecl = Dtor->getParent();
16047330f729Sjoerg     CGF.EmitDeleteCall(Dtor->getOperatorDelete(),
16057330f729Sjoerg                        LoadThisForDtorDelete(CGF, Dtor),
16067330f729Sjoerg                        CGF.getContext().getTagDeclType(ClassDecl));
16077330f729Sjoerg     assert(Dtor->getOperatorDelete()->isDestroyingOperatorDelete() ==
16087330f729Sjoerg                ReturnAfterDelete &&
16097330f729Sjoerg            "unexpected value for ReturnAfterDelete");
16107330f729Sjoerg     if (ReturnAfterDelete)
16117330f729Sjoerg       CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
16127330f729Sjoerg     else
16137330f729Sjoerg       CGF.Builder.CreateBr(continueBB);
16147330f729Sjoerg 
16157330f729Sjoerg     CGF.EmitBlock(continueBB);
16167330f729Sjoerg   }
16177330f729Sjoerg 
16187330f729Sjoerg   struct CallDtorDeleteConditional final : EHScopeStack::Cleanup {
16197330f729Sjoerg     llvm::Value *ShouldDeleteCondition;
16207330f729Sjoerg 
16217330f729Sjoerg   public:
CallDtorDeleteConditional__anonb72786c90411::CallDtorDeleteConditional16227330f729Sjoerg     CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition)
16237330f729Sjoerg         : ShouldDeleteCondition(ShouldDeleteCondition) {
16247330f729Sjoerg       assert(ShouldDeleteCondition != nullptr);
16257330f729Sjoerg     }
16267330f729Sjoerg 
Emit__anonb72786c90411::CallDtorDeleteConditional16277330f729Sjoerg     void Emit(CodeGenFunction &CGF, Flags flags) override {
16287330f729Sjoerg       EmitConditionalDtorDeleteCall(CGF, ShouldDeleteCondition,
16297330f729Sjoerg                                     /*ReturnAfterDelete*/false);
16307330f729Sjoerg     }
16317330f729Sjoerg   };
16327330f729Sjoerg 
16337330f729Sjoerg   class DestroyField  final : public EHScopeStack::Cleanup {
16347330f729Sjoerg     const FieldDecl *field;
16357330f729Sjoerg     CodeGenFunction::Destroyer *destroyer;
16367330f729Sjoerg     bool useEHCleanupForArray;
16377330f729Sjoerg 
16387330f729Sjoerg   public:
DestroyField(const FieldDecl * field,CodeGenFunction::Destroyer * destroyer,bool useEHCleanupForArray)16397330f729Sjoerg     DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer,
16407330f729Sjoerg                  bool useEHCleanupForArray)
16417330f729Sjoerg         : field(field), destroyer(destroyer),
16427330f729Sjoerg           useEHCleanupForArray(useEHCleanupForArray) {}
16437330f729Sjoerg 
Emit(CodeGenFunction & CGF,Flags flags)16447330f729Sjoerg     void Emit(CodeGenFunction &CGF, Flags flags) override {
16457330f729Sjoerg       // Find the address of the field.
16467330f729Sjoerg       Address thisValue = CGF.LoadCXXThisAddress();
16477330f729Sjoerg       QualType RecordTy = CGF.getContext().getTagDeclType(field->getParent());
16487330f729Sjoerg       LValue ThisLV = CGF.MakeAddrLValue(thisValue, RecordTy);
16497330f729Sjoerg       LValue LV = CGF.EmitLValueForField(ThisLV, field);
16507330f729Sjoerg       assert(LV.isSimple());
16517330f729Sjoerg 
1652*e038c9c4Sjoerg       CGF.emitDestroy(LV.getAddress(CGF), field->getType(), destroyer,
16537330f729Sjoerg                       flags.isForNormalCleanup() && useEHCleanupForArray);
16547330f729Sjoerg     }
16557330f729Sjoerg   };
16567330f729Sjoerg 
EmitSanitizerDtorCallback(CodeGenFunction & CGF,llvm::Value * Ptr,CharUnits::QuantityType PoisonSize)16577330f729Sjoerg  static void EmitSanitizerDtorCallback(CodeGenFunction &CGF, llvm::Value *Ptr,
16587330f729Sjoerg              CharUnits::QuantityType PoisonSize) {
16597330f729Sjoerg    CodeGenFunction::SanitizerScope SanScope(&CGF);
16607330f729Sjoerg    // Pass in void pointer and size of region as arguments to runtime
16617330f729Sjoerg    // function
16627330f729Sjoerg    llvm::Value *Args[] = {CGF.Builder.CreateBitCast(Ptr, CGF.VoidPtrTy),
16637330f729Sjoerg                           llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)};
16647330f729Sjoerg 
16657330f729Sjoerg    llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy};
16667330f729Sjoerg 
16677330f729Sjoerg    llvm::FunctionType *FnType =
16687330f729Sjoerg        llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
16697330f729Sjoerg    llvm::FunctionCallee Fn =
16707330f729Sjoerg        CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback");
16717330f729Sjoerg    CGF.EmitNounwindRuntimeCall(Fn, Args);
16727330f729Sjoerg  }
16737330f729Sjoerg 
16747330f729Sjoerg   class SanitizeDtorMembers final : public EHScopeStack::Cleanup {
16757330f729Sjoerg     const CXXDestructorDecl *Dtor;
16767330f729Sjoerg 
16777330f729Sjoerg   public:
SanitizeDtorMembers(const CXXDestructorDecl * Dtor)16787330f729Sjoerg     SanitizeDtorMembers(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
16797330f729Sjoerg 
16807330f729Sjoerg     // Generate function call for handling object poisoning.
16817330f729Sjoerg     // Disables tail call elimination, to prevent the current stack frame
16827330f729Sjoerg     // from disappearing from the stack trace.
Emit(CodeGenFunction & CGF,Flags flags)16837330f729Sjoerg     void Emit(CodeGenFunction &CGF, Flags flags) override {
16847330f729Sjoerg       const ASTRecordLayout &Layout =
16857330f729Sjoerg           CGF.getContext().getASTRecordLayout(Dtor->getParent());
16867330f729Sjoerg 
16877330f729Sjoerg       // Nothing to poison.
16887330f729Sjoerg       if (Layout.getFieldCount() == 0)
16897330f729Sjoerg         return;
16907330f729Sjoerg 
16917330f729Sjoerg       // Prevent the current stack frame from disappearing from the stack trace.
16927330f729Sjoerg       CGF.CurFn->addFnAttr("disable-tail-calls", "true");
16937330f729Sjoerg 
16947330f729Sjoerg       // Construct pointer to region to begin poisoning, and calculate poison
16957330f729Sjoerg       // size, so that only members declared in this class are poisoned.
16967330f729Sjoerg       ASTContext &Context = CGF.getContext();
16977330f729Sjoerg 
1698*e038c9c4Sjoerg       const RecordDecl *Decl = Dtor->getParent();
1699*e038c9c4Sjoerg       auto Fields = Decl->fields();
1700*e038c9c4Sjoerg       auto IsTrivial = [&](const FieldDecl *F) {
1701*e038c9c4Sjoerg         return FieldHasTrivialDestructorBody(Context, F);
1702*e038c9c4Sjoerg       };
1703*e038c9c4Sjoerg 
1704*e038c9c4Sjoerg       auto IsZeroSize = [&](const FieldDecl *F) {
1705*e038c9c4Sjoerg         return F->isZeroSize(Context);
1706*e038c9c4Sjoerg       };
1707*e038c9c4Sjoerg 
1708*e038c9c4Sjoerg       // Poison blocks of fields with trivial destructors making sure that block
1709*e038c9c4Sjoerg       // begin and end do not point to zero-sized fields. They don't have
1710*e038c9c4Sjoerg       // correct offsets so can't be used to calculate poisoning range.
1711*e038c9c4Sjoerg       for (auto It = Fields.begin(); It != Fields.end();) {
1712*e038c9c4Sjoerg         It = std::find_if(It, Fields.end(), [&](const FieldDecl *F) {
1713*e038c9c4Sjoerg           return IsTrivial(F) && !IsZeroSize(F);
1714*e038c9c4Sjoerg         });
1715*e038c9c4Sjoerg         if (It == Fields.end())
1716*e038c9c4Sjoerg           break;
1717*e038c9c4Sjoerg         auto Start = It++;
1718*e038c9c4Sjoerg         It = std::find_if(It, Fields.end(), [&](const FieldDecl *F) {
1719*e038c9c4Sjoerg           return !IsTrivial(F) && !IsZeroSize(F);
1720*e038c9c4Sjoerg         });
1721*e038c9c4Sjoerg 
1722*e038c9c4Sjoerg         PoisonMembers(CGF, (*Start)->getFieldIndex(),
1723*e038c9c4Sjoerg                       It == Fields.end() ? -1 : (*It)->getFieldIndex());
17247330f729Sjoerg       }
17257330f729Sjoerg     }
17267330f729Sjoerg 
17277330f729Sjoerg   private:
17287330f729Sjoerg     /// \param layoutStartOffset index of the ASTRecordLayout field to
17297330f729Sjoerg     ///     start poisoning (inclusive)
17307330f729Sjoerg     /// \param layoutEndOffset index of the ASTRecordLayout field to
17317330f729Sjoerg     ///     end poisoning (exclusive)
PoisonMembers(CodeGenFunction & CGF,unsigned layoutStartOffset,unsigned layoutEndOffset)17327330f729Sjoerg     void PoisonMembers(CodeGenFunction &CGF, unsigned layoutStartOffset,
17337330f729Sjoerg                        unsigned layoutEndOffset) {
17347330f729Sjoerg       ASTContext &Context = CGF.getContext();
17357330f729Sjoerg       const ASTRecordLayout &Layout =
17367330f729Sjoerg           Context.getASTRecordLayout(Dtor->getParent());
17377330f729Sjoerg 
1738*e038c9c4Sjoerg       // It's a first trivia field so it should be at the begining of char,
1739*e038c9c4Sjoerg       // still round up start offset just in case.
1740*e038c9c4Sjoerg       CharUnits PoisonStart =
1741*e038c9c4Sjoerg           Context.toCharUnitsFromBits(Layout.getFieldOffset(layoutStartOffset) +
1742*e038c9c4Sjoerg                                       Context.getCharWidth() - 1);
1743*e038c9c4Sjoerg       llvm::ConstantInt *OffsetSizePtr =
1744*e038c9c4Sjoerg           llvm::ConstantInt::get(CGF.SizeTy, PoisonStart.getQuantity());
17457330f729Sjoerg 
17467330f729Sjoerg       llvm::Value *OffsetPtr = CGF.Builder.CreateGEP(
17477330f729Sjoerg           CGF.Builder.CreateBitCast(CGF.LoadCXXThis(), CGF.Int8PtrTy),
17487330f729Sjoerg           OffsetSizePtr);
17497330f729Sjoerg 
1750*e038c9c4Sjoerg       CharUnits PoisonEnd;
17517330f729Sjoerg       if (layoutEndOffset >= Layout.getFieldCount()) {
1752*e038c9c4Sjoerg         PoisonEnd = Layout.getNonVirtualSize();
17537330f729Sjoerg       } else {
1754*e038c9c4Sjoerg         PoisonEnd =
1755*e038c9c4Sjoerg             Context.toCharUnitsFromBits(Layout.getFieldOffset(layoutEndOffset));
17567330f729Sjoerg       }
1757*e038c9c4Sjoerg       CharUnits PoisonSize = PoisonEnd - PoisonStart;
1758*e038c9c4Sjoerg       if (!PoisonSize.isPositive())
17597330f729Sjoerg         return;
17607330f729Sjoerg 
1761*e038c9c4Sjoerg       EmitSanitizerDtorCallback(CGF, OffsetPtr, PoisonSize.getQuantity());
17627330f729Sjoerg     }
17637330f729Sjoerg   };
17647330f729Sjoerg 
17657330f729Sjoerg  class SanitizeDtorVTable final : public EHScopeStack::Cleanup {
17667330f729Sjoerg     const CXXDestructorDecl *Dtor;
17677330f729Sjoerg 
17687330f729Sjoerg   public:
SanitizeDtorVTable(const CXXDestructorDecl * Dtor)17697330f729Sjoerg     SanitizeDtorVTable(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
17707330f729Sjoerg 
17717330f729Sjoerg     // Generate function call for handling vtable pointer poisoning.
Emit(CodeGenFunction & CGF,Flags flags)17727330f729Sjoerg     void Emit(CodeGenFunction &CGF, Flags flags) override {
17737330f729Sjoerg       assert(Dtor->getParent()->isDynamicClass());
17747330f729Sjoerg       (void)Dtor;
17757330f729Sjoerg       ASTContext &Context = CGF.getContext();
17767330f729Sjoerg       // Poison vtable and vtable ptr if they exist for this class.
17777330f729Sjoerg       llvm::Value *VTablePtr = CGF.LoadCXXThis();
17787330f729Sjoerg 
17797330f729Sjoerg       CharUnits::QuantityType PoisonSize =
17807330f729Sjoerg           Context.toCharUnitsFromBits(CGF.PointerWidthInBits).getQuantity();
17817330f729Sjoerg       // Pass in void pointer and size of region as arguments to runtime
17827330f729Sjoerg       // function
17837330f729Sjoerg       EmitSanitizerDtorCallback(CGF, VTablePtr, PoisonSize);
17847330f729Sjoerg     }
17857330f729Sjoerg  };
17867330f729Sjoerg } // end anonymous namespace
17877330f729Sjoerg 
17887330f729Sjoerg /// Emit all code that comes at the end of class's
17897330f729Sjoerg /// destructor. This is to call destructors on members and base classes
17907330f729Sjoerg /// in reverse order of their construction.
17917330f729Sjoerg ///
17927330f729Sjoerg /// For a deleting destructor, this also handles the case where a destroying
17937330f729Sjoerg /// operator delete completely overrides the definition.
EnterDtorCleanups(const CXXDestructorDecl * DD,CXXDtorType DtorType)17947330f729Sjoerg void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD,
17957330f729Sjoerg                                         CXXDtorType DtorType) {
17967330f729Sjoerg   assert((!DD->isTrivial() || DD->hasAttr<DLLExportAttr>()) &&
17977330f729Sjoerg          "Should not emit dtor epilogue for non-exported trivial dtor!");
17987330f729Sjoerg 
17997330f729Sjoerg   // The deleting-destructor phase just needs to call the appropriate
18007330f729Sjoerg   // operator delete that Sema picked up.
18017330f729Sjoerg   if (DtorType == Dtor_Deleting) {
18027330f729Sjoerg     assert(DD->getOperatorDelete() &&
18037330f729Sjoerg            "operator delete missing - EnterDtorCleanups");
18047330f729Sjoerg     if (CXXStructorImplicitParamValue) {
18057330f729Sjoerg       // If there is an implicit param to the deleting dtor, it's a boolean
18067330f729Sjoerg       // telling whether this is a deleting destructor.
18077330f729Sjoerg       if (DD->getOperatorDelete()->isDestroyingOperatorDelete())
18087330f729Sjoerg         EmitConditionalDtorDeleteCall(*this, CXXStructorImplicitParamValue,
18097330f729Sjoerg                                       /*ReturnAfterDelete*/true);
18107330f729Sjoerg       else
18117330f729Sjoerg         EHStack.pushCleanup<CallDtorDeleteConditional>(
18127330f729Sjoerg             NormalAndEHCleanup, CXXStructorImplicitParamValue);
18137330f729Sjoerg     } else {
18147330f729Sjoerg       if (DD->getOperatorDelete()->isDestroyingOperatorDelete()) {
18157330f729Sjoerg         const CXXRecordDecl *ClassDecl = DD->getParent();
18167330f729Sjoerg         EmitDeleteCall(DD->getOperatorDelete(),
18177330f729Sjoerg                        LoadThisForDtorDelete(*this, DD),
18187330f729Sjoerg                        getContext().getTagDeclType(ClassDecl));
18197330f729Sjoerg         EmitBranchThroughCleanup(ReturnBlock);
18207330f729Sjoerg       } else {
18217330f729Sjoerg         EHStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup);
18227330f729Sjoerg       }
18237330f729Sjoerg     }
18247330f729Sjoerg     return;
18257330f729Sjoerg   }
18267330f729Sjoerg 
18277330f729Sjoerg   const CXXRecordDecl *ClassDecl = DD->getParent();
18287330f729Sjoerg 
18297330f729Sjoerg   // Unions have no bases and do not call field destructors.
18307330f729Sjoerg   if (ClassDecl->isUnion())
18317330f729Sjoerg     return;
18327330f729Sjoerg 
18337330f729Sjoerg   // The complete-destructor phase just destructs all the virtual bases.
18347330f729Sjoerg   if (DtorType == Dtor_Complete) {
18357330f729Sjoerg     // Poison the vtable pointer such that access after the base
18367330f729Sjoerg     // and member destructors are invoked is invalid.
18377330f729Sjoerg     if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
18387330f729Sjoerg         SanOpts.has(SanitizerKind::Memory) && ClassDecl->getNumVBases() &&
18397330f729Sjoerg         ClassDecl->isPolymorphic())
18407330f729Sjoerg       EHStack.pushCleanup<SanitizeDtorVTable>(NormalAndEHCleanup, DD);
18417330f729Sjoerg 
18427330f729Sjoerg     // We push them in the forward order so that they'll be popped in
18437330f729Sjoerg     // the reverse order.
18447330f729Sjoerg     for (const auto &Base : ClassDecl->vbases()) {
18457330f729Sjoerg       auto *BaseClassDecl =
18467330f729Sjoerg           cast<CXXRecordDecl>(Base.getType()->castAs<RecordType>()->getDecl());
18477330f729Sjoerg 
18487330f729Sjoerg       // Ignore trivial destructors.
18497330f729Sjoerg       if (BaseClassDecl->hasTrivialDestructor())
18507330f729Sjoerg         continue;
18517330f729Sjoerg 
18527330f729Sjoerg       EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup,
18537330f729Sjoerg                                         BaseClassDecl,
18547330f729Sjoerg                                         /*BaseIsVirtual*/ true);
18557330f729Sjoerg     }
18567330f729Sjoerg 
18577330f729Sjoerg     return;
18587330f729Sjoerg   }
18597330f729Sjoerg 
18607330f729Sjoerg   assert(DtorType == Dtor_Base);
18617330f729Sjoerg   // Poison the vtable pointer if it has no virtual bases, but inherits
18627330f729Sjoerg   // virtual functions.
18637330f729Sjoerg   if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
18647330f729Sjoerg       SanOpts.has(SanitizerKind::Memory) && !ClassDecl->getNumVBases() &&
18657330f729Sjoerg       ClassDecl->isPolymorphic())
18667330f729Sjoerg     EHStack.pushCleanup<SanitizeDtorVTable>(NormalAndEHCleanup, DD);
18677330f729Sjoerg 
18687330f729Sjoerg   // Destroy non-virtual bases.
18697330f729Sjoerg   for (const auto &Base : ClassDecl->bases()) {
18707330f729Sjoerg     // Ignore virtual bases.
18717330f729Sjoerg     if (Base.isVirtual())
18727330f729Sjoerg       continue;
18737330f729Sjoerg 
18747330f729Sjoerg     CXXRecordDecl *BaseClassDecl = Base.getType()->getAsCXXRecordDecl();
18757330f729Sjoerg 
18767330f729Sjoerg     // Ignore trivial destructors.
18777330f729Sjoerg     if (BaseClassDecl->hasTrivialDestructor())
18787330f729Sjoerg       continue;
18797330f729Sjoerg 
18807330f729Sjoerg     EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup,
18817330f729Sjoerg                                       BaseClassDecl,
18827330f729Sjoerg                                       /*BaseIsVirtual*/ false);
18837330f729Sjoerg   }
18847330f729Sjoerg 
18857330f729Sjoerg   // Poison fields such that access after their destructors are
18867330f729Sjoerg   // invoked, and before the base class destructor runs, is invalid.
18877330f729Sjoerg   if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
18887330f729Sjoerg       SanOpts.has(SanitizerKind::Memory))
18897330f729Sjoerg     EHStack.pushCleanup<SanitizeDtorMembers>(NormalAndEHCleanup, DD);
18907330f729Sjoerg 
18917330f729Sjoerg   // Destroy direct fields.
18927330f729Sjoerg   for (const auto *Field : ClassDecl->fields()) {
18937330f729Sjoerg     QualType type = Field->getType();
18947330f729Sjoerg     QualType::DestructionKind dtorKind = type.isDestructedType();
18957330f729Sjoerg     if (!dtorKind) continue;
18967330f729Sjoerg 
18977330f729Sjoerg     // Anonymous union members do not have their destructors called.
18987330f729Sjoerg     const RecordType *RT = type->getAsUnionType();
18997330f729Sjoerg     if (RT && RT->getDecl()->isAnonymousStructOrUnion()) continue;
19007330f729Sjoerg 
19017330f729Sjoerg     CleanupKind cleanupKind = getCleanupKind(dtorKind);
19027330f729Sjoerg     EHStack.pushCleanup<DestroyField>(cleanupKind, Field,
19037330f729Sjoerg                                       getDestroyer(dtorKind),
19047330f729Sjoerg                                       cleanupKind & EHCleanup);
19057330f729Sjoerg   }
19067330f729Sjoerg }
19077330f729Sjoerg 
19087330f729Sjoerg /// EmitCXXAggrConstructorCall - Emit a loop to call a particular
19097330f729Sjoerg /// constructor for each of several members of an array.
19107330f729Sjoerg ///
19117330f729Sjoerg /// \param ctor the constructor to call for each element
19127330f729Sjoerg /// \param arrayType the type of the array to initialize
19137330f729Sjoerg /// \param arrayBegin an arrayType*
19147330f729Sjoerg /// \param zeroInitialize true if each element should be
19157330f729Sjoerg ///   zero-initialized before it is constructed
EmitCXXAggrConstructorCall(const CXXConstructorDecl * ctor,const ArrayType * arrayType,Address arrayBegin,const CXXConstructExpr * E,bool NewPointerIsChecked,bool zeroInitialize)19167330f729Sjoerg void CodeGenFunction::EmitCXXAggrConstructorCall(
19177330f729Sjoerg     const CXXConstructorDecl *ctor, const ArrayType *arrayType,
19187330f729Sjoerg     Address arrayBegin, const CXXConstructExpr *E, bool NewPointerIsChecked,
19197330f729Sjoerg     bool zeroInitialize) {
19207330f729Sjoerg   QualType elementType;
19217330f729Sjoerg   llvm::Value *numElements =
19227330f729Sjoerg     emitArrayLength(arrayType, elementType, arrayBegin);
19237330f729Sjoerg 
19247330f729Sjoerg   EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, E,
19257330f729Sjoerg                              NewPointerIsChecked, zeroInitialize);
19267330f729Sjoerg }
19277330f729Sjoerg 
19287330f729Sjoerg /// EmitCXXAggrConstructorCall - Emit a loop to call a particular
19297330f729Sjoerg /// constructor for each of several members of an array.
19307330f729Sjoerg ///
19317330f729Sjoerg /// \param ctor the constructor to call for each element
19327330f729Sjoerg /// \param numElements the number of elements in the array;
19337330f729Sjoerg ///   may be zero
19347330f729Sjoerg /// \param arrayBase a T*, where T is the type constructed by ctor
19357330f729Sjoerg /// \param zeroInitialize true if each element should be
19367330f729Sjoerg ///   zero-initialized before it is constructed
EmitCXXAggrConstructorCall(const CXXConstructorDecl * ctor,llvm::Value * numElements,Address arrayBase,const CXXConstructExpr * E,bool NewPointerIsChecked,bool zeroInitialize)19377330f729Sjoerg void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor,
19387330f729Sjoerg                                                  llvm::Value *numElements,
19397330f729Sjoerg                                                  Address arrayBase,
19407330f729Sjoerg                                                  const CXXConstructExpr *E,
19417330f729Sjoerg                                                  bool NewPointerIsChecked,
19427330f729Sjoerg                                                  bool zeroInitialize) {
19437330f729Sjoerg   // It's legal for numElements to be zero.  This can happen both
19447330f729Sjoerg   // dynamically, because x can be zero in 'new A[x]', and statically,
19457330f729Sjoerg   // because of GCC extensions that permit zero-length arrays.  There
19467330f729Sjoerg   // are probably legitimate places where we could assume that this
19477330f729Sjoerg   // doesn't happen, but it's not clear that it's worth it.
19487330f729Sjoerg   llvm::BranchInst *zeroCheckBranch = nullptr;
19497330f729Sjoerg 
19507330f729Sjoerg   // Optimize for a constant count.
19517330f729Sjoerg   llvm::ConstantInt *constantCount
19527330f729Sjoerg     = dyn_cast<llvm::ConstantInt>(numElements);
19537330f729Sjoerg   if (constantCount) {
19547330f729Sjoerg     // Just skip out if the constant count is zero.
19557330f729Sjoerg     if (constantCount->isZero()) return;
19567330f729Sjoerg 
19577330f729Sjoerg   // Otherwise, emit the check.
19587330f729Sjoerg   } else {
19597330f729Sjoerg     llvm::BasicBlock *loopBB = createBasicBlock("new.ctorloop");
19607330f729Sjoerg     llvm::Value *iszero = Builder.CreateIsNull(numElements, "isempty");
19617330f729Sjoerg     zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB);
19627330f729Sjoerg     EmitBlock(loopBB);
19637330f729Sjoerg   }
19647330f729Sjoerg 
19657330f729Sjoerg   // Find the end of the array.
1966*e038c9c4Sjoerg   llvm::Type *elementType = arrayBase.getElementType();
19677330f729Sjoerg   llvm::Value *arrayBegin = arrayBase.getPointer();
1968*e038c9c4Sjoerg   llvm::Value *arrayEnd = Builder.CreateInBoundsGEP(
1969*e038c9c4Sjoerg       elementType, arrayBegin, numElements, "arrayctor.end");
19707330f729Sjoerg 
19717330f729Sjoerg   // Enter the loop, setting up a phi for the current location to initialize.
19727330f729Sjoerg   llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
19737330f729Sjoerg   llvm::BasicBlock *loopBB = createBasicBlock("arrayctor.loop");
19747330f729Sjoerg   EmitBlock(loopBB);
19757330f729Sjoerg   llvm::PHINode *cur = Builder.CreatePHI(arrayBegin->getType(), 2,
19767330f729Sjoerg                                          "arrayctor.cur");
19777330f729Sjoerg   cur->addIncoming(arrayBegin, entryBB);
19787330f729Sjoerg 
19797330f729Sjoerg   // Inside the loop body, emit the constructor call on the array element.
19807330f729Sjoerg 
19817330f729Sjoerg   // The alignment of the base, adjusted by the size of a single element,
19827330f729Sjoerg   // provides a conservative estimate of the alignment of every element.
19837330f729Sjoerg   // (This assumes we never start tracking offsetted alignments.)
19847330f729Sjoerg   //
19857330f729Sjoerg   // Note that these are complete objects and so we don't need to
19867330f729Sjoerg   // use the non-virtual size or alignment.
19877330f729Sjoerg   QualType type = getContext().getTypeDeclType(ctor->getParent());
19887330f729Sjoerg   CharUnits eltAlignment =
19897330f729Sjoerg     arrayBase.getAlignment()
19907330f729Sjoerg              .alignmentOfArrayElement(getContext().getTypeSizeInChars(type));
19917330f729Sjoerg   Address curAddr = Address(cur, eltAlignment);
19927330f729Sjoerg 
19937330f729Sjoerg   // Zero initialize the storage, if requested.
19947330f729Sjoerg   if (zeroInitialize)
19957330f729Sjoerg     EmitNullInitialization(curAddr, type);
19967330f729Sjoerg 
19977330f729Sjoerg   // C++ [class.temporary]p4:
19987330f729Sjoerg   // There are two contexts in which temporaries are destroyed at a different
19997330f729Sjoerg   // point than the end of the full-expression. The first context is when a
20007330f729Sjoerg   // default constructor is called to initialize an element of an array.
20017330f729Sjoerg   // If the constructor has one or more default arguments, the destruction of
20027330f729Sjoerg   // every temporary created in a default argument expression is sequenced
20037330f729Sjoerg   // before the construction of the next array element, if any.
20047330f729Sjoerg 
20057330f729Sjoerg   {
20067330f729Sjoerg     RunCleanupsScope Scope(*this);
20077330f729Sjoerg 
20087330f729Sjoerg     // Evaluate the constructor and its arguments in a regular
20097330f729Sjoerg     // partial-destroy cleanup.
20107330f729Sjoerg     if (getLangOpts().Exceptions &&
20117330f729Sjoerg         !ctor->getParent()->hasTrivialDestructor()) {
20127330f729Sjoerg       Destroyer *destroyer = destroyCXXObject;
20137330f729Sjoerg       pushRegularPartialArrayCleanup(arrayBegin, cur, type, eltAlignment,
20147330f729Sjoerg                                      *destroyer);
20157330f729Sjoerg     }
20167330f729Sjoerg     auto currAVS = AggValueSlot::forAddr(
20177330f729Sjoerg         curAddr, type.getQualifiers(), AggValueSlot::IsDestructed,
20187330f729Sjoerg         AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased,
20197330f729Sjoerg         AggValueSlot::DoesNotOverlap, AggValueSlot::IsNotZeroed,
20207330f729Sjoerg         NewPointerIsChecked ? AggValueSlot::IsSanitizerChecked
20217330f729Sjoerg                             : AggValueSlot::IsNotSanitizerChecked);
20227330f729Sjoerg     EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/false,
20237330f729Sjoerg                            /*Delegating=*/false, currAVS, E);
20247330f729Sjoerg   }
20257330f729Sjoerg 
20267330f729Sjoerg   // Go to the next element.
2027*e038c9c4Sjoerg   llvm::Value *next = Builder.CreateInBoundsGEP(
2028*e038c9c4Sjoerg       elementType, cur, llvm::ConstantInt::get(SizeTy, 1), "arrayctor.next");
20297330f729Sjoerg   cur->addIncoming(next, Builder.GetInsertBlock());
20307330f729Sjoerg 
20317330f729Sjoerg   // Check whether that's the end of the loop.
20327330f729Sjoerg   llvm::Value *done = Builder.CreateICmpEQ(next, arrayEnd, "arrayctor.done");
20337330f729Sjoerg   llvm::BasicBlock *contBB = createBasicBlock("arrayctor.cont");
20347330f729Sjoerg   Builder.CreateCondBr(done, contBB, loopBB);
20357330f729Sjoerg 
20367330f729Sjoerg   // Patch the earlier check to skip over the loop.
20377330f729Sjoerg   if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB);
20387330f729Sjoerg 
20397330f729Sjoerg   EmitBlock(contBB);
20407330f729Sjoerg }
20417330f729Sjoerg 
destroyCXXObject(CodeGenFunction & CGF,Address addr,QualType type)20427330f729Sjoerg void CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF,
20437330f729Sjoerg                                        Address addr,
20447330f729Sjoerg                                        QualType type) {
20457330f729Sjoerg   const RecordType *rtype = type->castAs<RecordType>();
20467330f729Sjoerg   const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl());
20477330f729Sjoerg   const CXXDestructorDecl *dtor = record->getDestructor();
20487330f729Sjoerg   assert(!dtor->isTrivial());
20497330f729Sjoerg   CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false,
20507330f729Sjoerg                             /*Delegating=*/false, addr, type);
20517330f729Sjoerg }
20527330f729Sjoerg 
EmitCXXConstructorCall(const CXXConstructorDecl * D,CXXCtorType Type,bool ForVirtualBase,bool Delegating,AggValueSlot ThisAVS,const CXXConstructExpr * E)20537330f729Sjoerg void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
20547330f729Sjoerg                                              CXXCtorType Type,
20557330f729Sjoerg                                              bool ForVirtualBase,
20567330f729Sjoerg                                              bool Delegating,
20577330f729Sjoerg                                              AggValueSlot ThisAVS,
20587330f729Sjoerg                                              const CXXConstructExpr *E) {
20597330f729Sjoerg   CallArgList Args;
20607330f729Sjoerg   Address This = ThisAVS.getAddress();
20617330f729Sjoerg   LangAS SlotAS = ThisAVS.getQualifiers().getAddressSpace();
20627330f729Sjoerg   QualType ThisType = D->getThisType();
20637330f729Sjoerg   LangAS ThisAS = ThisType.getTypePtr()->getPointeeType().getAddressSpace();
20647330f729Sjoerg   llvm::Value *ThisPtr = This.getPointer();
20657330f729Sjoerg 
20667330f729Sjoerg   if (SlotAS != ThisAS) {
20677330f729Sjoerg     unsigned TargetThisAS = getContext().getTargetAddressSpace(ThisAS);
20687330f729Sjoerg     llvm::Type *NewType =
20697330f729Sjoerg         ThisPtr->getType()->getPointerElementType()->getPointerTo(TargetThisAS);
20707330f729Sjoerg     ThisPtr = getTargetHooks().performAddrSpaceCast(*this, This.getPointer(),
20717330f729Sjoerg                                                     ThisAS, SlotAS, NewType);
20727330f729Sjoerg   }
20737330f729Sjoerg 
20747330f729Sjoerg   // Push the this ptr.
20757330f729Sjoerg   Args.add(RValue::get(ThisPtr), D->getThisType());
20767330f729Sjoerg 
20777330f729Sjoerg   // If this is a trivial constructor, emit a memcpy now before we lose
20787330f729Sjoerg   // the alignment information on the argument.
20797330f729Sjoerg   // FIXME: It would be better to preserve alignment information into CallArg.
20807330f729Sjoerg   if (isMemcpyEquivalentSpecialMember(D)) {
20817330f729Sjoerg     assert(E->getNumArgs() == 1 && "unexpected argcount for trivial ctor");
20827330f729Sjoerg 
20837330f729Sjoerg     const Expr *Arg = E->getArg(0);
20847330f729Sjoerg     LValue Src = EmitLValue(Arg);
20857330f729Sjoerg     QualType DestTy = getContext().getTypeDeclType(D->getParent());
20867330f729Sjoerg     LValue Dest = MakeAddrLValue(This, DestTy);
20877330f729Sjoerg     EmitAggregateCopyCtor(Dest, Src, ThisAVS.mayOverlap());
20887330f729Sjoerg     return;
20897330f729Sjoerg   }
20907330f729Sjoerg 
20917330f729Sjoerg   // Add the rest of the user-supplied arguments.
20927330f729Sjoerg   const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
20937330f729Sjoerg   EvaluationOrder Order = E->isListInitialization()
20947330f729Sjoerg                               ? EvaluationOrder::ForceLeftToRight
20957330f729Sjoerg                               : EvaluationOrder::Default;
20967330f729Sjoerg   EmitCallArgs(Args, FPT, E->arguments(), E->getConstructor(),
20977330f729Sjoerg                /*ParamsToSkip*/ 0, Order);
20987330f729Sjoerg 
20997330f729Sjoerg   EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args,
21007330f729Sjoerg                          ThisAVS.mayOverlap(), E->getExprLoc(),
21017330f729Sjoerg                          ThisAVS.isSanitizerChecked());
21027330f729Sjoerg }
21037330f729Sjoerg 
canEmitDelegateCallArgs(CodeGenFunction & CGF,const CXXConstructorDecl * Ctor,CXXCtorType Type,CallArgList & Args)21047330f729Sjoerg static bool canEmitDelegateCallArgs(CodeGenFunction &CGF,
21057330f729Sjoerg                                     const CXXConstructorDecl *Ctor,
21067330f729Sjoerg                                     CXXCtorType Type, CallArgList &Args) {
21077330f729Sjoerg   // We can't forward a variadic call.
21087330f729Sjoerg   if (Ctor->isVariadic())
21097330f729Sjoerg     return false;
21107330f729Sjoerg 
21117330f729Sjoerg   if (CGF.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
21127330f729Sjoerg     // If the parameters are callee-cleanup, it's not safe to forward.
21137330f729Sjoerg     for (auto *P : Ctor->parameters())
21147330f729Sjoerg       if (P->needsDestruction(CGF.getContext()))
21157330f729Sjoerg         return false;
21167330f729Sjoerg 
21177330f729Sjoerg     // Likewise if they're inalloca.
21187330f729Sjoerg     const CGFunctionInfo &Info =
21197330f729Sjoerg         CGF.CGM.getTypes().arrangeCXXConstructorCall(Args, Ctor, Type, 0, 0);
21207330f729Sjoerg     if (Info.usesInAlloca())
21217330f729Sjoerg       return false;
21227330f729Sjoerg   }
21237330f729Sjoerg 
21247330f729Sjoerg   // Anything else should be OK.
21257330f729Sjoerg   return true;
21267330f729Sjoerg }
21277330f729Sjoerg 
EmitCXXConstructorCall(const CXXConstructorDecl * D,CXXCtorType Type,bool ForVirtualBase,bool Delegating,Address This,CallArgList & Args,AggValueSlot::Overlap_t Overlap,SourceLocation Loc,bool NewPointerIsChecked)21287330f729Sjoerg void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
21297330f729Sjoerg                                              CXXCtorType Type,
21307330f729Sjoerg                                              bool ForVirtualBase,
21317330f729Sjoerg                                              bool Delegating,
21327330f729Sjoerg                                              Address This,
21337330f729Sjoerg                                              CallArgList &Args,
21347330f729Sjoerg                                              AggValueSlot::Overlap_t Overlap,
21357330f729Sjoerg                                              SourceLocation Loc,
21367330f729Sjoerg                                              bool NewPointerIsChecked) {
21377330f729Sjoerg   const CXXRecordDecl *ClassDecl = D->getParent();
21387330f729Sjoerg 
21397330f729Sjoerg   if (!NewPointerIsChecked)
21407330f729Sjoerg     EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, Loc, This.getPointer(),
21417330f729Sjoerg                   getContext().getRecordType(ClassDecl), CharUnits::Zero());
21427330f729Sjoerg 
21437330f729Sjoerg   if (D->isTrivial() && D->isDefaultConstructor()) {
21447330f729Sjoerg     assert(Args.size() == 1 && "trivial default ctor with args");
21457330f729Sjoerg     return;
21467330f729Sjoerg   }
21477330f729Sjoerg 
21487330f729Sjoerg   // If this is a trivial constructor, just emit what's needed. If this is a
21497330f729Sjoerg   // union copy constructor, we must emit a memcpy, because the AST does not
21507330f729Sjoerg   // model that copy.
21517330f729Sjoerg   if (isMemcpyEquivalentSpecialMember(D)) {
21527330f729Sjoerg     assert(Args.size() == 2 && "unexpected argcount for trivial ctor");
21537330f729Sjoerg 
21547330f729Sjoerg     QualType SrcTy = D->getParamDecl(0)->getType().getNonReferenceType();
21557330f729Sjoerg     Address Src(Args[1].getRValue(*this).getScalarVal(),
2156*e038c9c4Sjoerg                 CGM.getNaturalTypeAlignment(SrcTy));
21577330f729Sjoerg     LValue SrcLVal = MakeAddrLValue(Src, SrcTy);
21587330f729Sjoerg     QualType DestTy = getContext().getTypeDeclType(ClassDecl);
21597330f729Sjoerg     LValue DestLVal = MakeAddrLValue(This, DestTy);
21607330f729Sjoerg     EmitAggregateCopyCtor(DestLVal, SrcLVal, Overlap);
21617330f729Sjoerg     return;
21627330f729Sjoerg   }
21637330f729Sjoerg 
21647330f729Sjoerg   bool PassPrototypeArgs = true;
21657330f729Sjoerg   // Check whether we can actually emit the constructor before trying to do so.
21667330f729Sjoerg   if (auto Inherited = D->getInheritedConstructor()) {
21677330f729Sjoerg     PassPrototypeArgs = getTypes().inheritingCtorHasParams(Inherited, Type);
21687330f729Sjoerg     if (PassPrototypeArgs && !canEmitDelegateCallArgs(*this, D, Type, Args)) {
21697330f729Sjoerg       EmitInlinedInheritingCXXConstructorCall(D, Type, ForVirtualBase,
21707330f729Sjoerg                                               Delegating, Args);
21717330f729Sjoerg       return;
21727330f729Sjoerg     }
21737330f729Sjoerg   }
21747330f729Sjoerg 
21757330f729Sjoerg   // Insert any ABI-specific implicit constructor arguments.
2176*e038c9c4Sjoerg   CGCXXABI::AddedStructorArgCounts ExtraArgs =
21777330f729Sjoerg       CGM.getCXXABI().addImplicitConstructorArgs(*this, D, Type, ForVirtualBase,
21787330f729Sjoerg                                                  Delegating, Args);
21797330f729Sjoerg 
21807330f729Sjoerg   // Emit the call.
21817330f729Sjoerg   llvm::Constant *CalleePtr = CGM.getAddrOfCXXStructor(GlobalDecl(D, Type));
21827330f729Sjoerg   const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall(
21837330f729Sjoerg       Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs);
21847330f729Sjoerg   CGCallee Callee = CGCallee::forDirect(CalleePtr, GlobalDecl(D, Type));
2185*e038c9c4Sjoerg   EmitCall(Info, Callee, ReturnValueSlot(), Args, nullptr, false, Loc);
21867330f729Sjoerg 
21877330f729Sjoerg   // Generate vtable assumptions if we're constructing a complete object
21887330f729Sjoerg   // with a vtable.  We don't do this for base subobjects for two reasons:
21897330f729Sjoerg   // first, it's incorrect for classes with virtual bases, and second, we're
21907330f729Sjoerg   // about to overwrite the vptrs anyway.
21917330f729Sjoerg   // We also have to make sure if we can refer to vtable:
21927330f729Sjoerg   // - Otherwise we can refer to vtable if it's safe to speculatively emit.
21937330f729Sjoerg   // FIXME: If vtable is used by ctor/dtor, or if vtable is external and we are
21947330f729Sjoerg   // sure that definition of vtable is not hidden,
21957330f729Sjoerg   // then we are always safe to refer to it.
21967330f729Sjoerg   // FIXME: It looks like InstCombine is very inefficient on dealing with
21977330f729Sjoerg   // assumes. Make assumption loads require -fstrict-vtable-pointers temporarily.
21987330f729Sjoerg   if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
21997330f729Sjoerg       ClassDecl->isDynamicClass() && Type != Ctor_Base &&
22007330f729Sjoerg       CGM.getCXXABI().canSpeculativelyEmitVTable(ClassDecl) &&
22017330f729Sjoerg       CGM.getCodeGenOpts().StrictVTablePointers)
22027330f729Sjoerg     EmitVTableAssumptionLoads(ClassDecl, This);
22037330f729Sjoerg }
22047330f729Sjoerg 
EmitInheritedCXXConstructorCall(const CXXConstructorDecl * D,bool ForVirtualBase,Address This,bool InheritedFromVBase,const CXXInheritedCtorInitExpr * E)22057330f729Sjoerg void CodeGenFunction::EmitInheritedCXXConstructorCall(
22067330f729Sjoerg     const CXXConstructorDecl *D, bool ForVirtualBase, Address This,
22077330f729Sjoerg     bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E) {
22087330f729Sjoerg   CallArgList Args;
22097330f729Sjoerg   CallArg ThisArg(RValue::get(This.getPointer()), D->getThisType());
22107330f729Sjoerg 
22117330f729Sjoerg   // Forward the parameters.
22127330f729Sjoerg   if (InheritedFromVBase &&
22137330f729Sjoerg       CGM.getTarget().getCXXABI().hasConstructorVariants()) {
22147330f729Sjoerg     // Nothing to do; this construction is not responsible for constructing
22157330f729Sjoerg     // the base class containing the inherited constructor.
22167330f729Sjoerg     // FIXME: Can we just pass undef's for the remaining arguments if we don't
22177330f729Sjoerg     // have constructor variants?
22187330f729Sjoerg     Args.push_back(ThisArg);
22197330f729Sjoerg   } else if (!CXXInheritedCtorInitExprArgs.empty()) {
22207330f729Sjoerg     // The inheriting constructor was inlined; just inject its arguments.
22217330f729Sjoerg     assert(CXXInheritedCtorInitExprArgs.size() >= D->getNumParams() &&
22227330f729Sjoerg            "wrong number of parameters for inherited constructor call");
22237330f729Sjoerg     Args = CXXInheritedCtorInitExprArgs;
22247330f729Sjoerg     Args[0] = ThisArg;
22257330f729Sjoerg   } else {
22267330f729Sjoerg     // The inheriting constructor was not inlined. Emit delegating arguments.
22277330f729Sjoerg     Args.push_back(ThisArg);
22287330f729Sjoerg     const auto *OuterCtor = cast<CXXConstructorDecl>(CurCodeDecl);
22297330f729Sjoerg     assert(OuterCtor->getNumParams() == D->getNumParams());
22307330f729Sjoerg     assert(!OuterCtor->isVariadic() && "should have been inlined");
22317330f729Sjoerg 
22327330f729Sjoerg     for (const auto *Param : OuterCtor->parameters()) {
22337330f729Sjoerg       assert(getContext().hasSameUnqualifiedType(
22347330f729Sjoerg           OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->getType(),
22357330f729Sjoerg           Param->getType()));
22367330f729Sjoerg       EmitDelegateCallArg(Args, Param, E->getLocation());
22377330f729Sjoerg 
22387330f729Sjoerg       // Forward __attribute__(pass_object_size).
22397330f729Sjoerg       if (Param->hasAttr<PassObjectSizeAttr>()) {
22407330f729Sjoerg         auto *POSParam = SizeArguments[Param];
22417330f729Sjoerg         assert(POSParam && "missing pass_object_size value for forwarding");
22427330f729Sjoerg         EmitDelegateCallArg(Args, POSParam, E->getLocation());
22437330f729Sjoerg       }
22447330f729Sjoerg     }
22457330f729Sjoerg   }
22467330f729Sjoerg 
22477330f729Sjoerg   EmitCXXConstructorCall(D, Ctor_Base, ForVirtualBase, /*Delegating*/false,
22487330f729Sjoerg                          This, Args, AggValueSlot::MayOverlap,
22497330f729Sjoerg                          E->getLocation(), /*NewPointerIsChecked*/true);
22507330f729Sjoerg }
22517330f729Sjoerg 
EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl * Ctor,CXXCtorType CtorType,bool ForVirtualBase,bool Delegating,CallArgList & Args)22527330f729Sjoerg void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall(
22537330f729Sjoerg     const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase,
22547330f729Sjoerg     bool Delegating, CallArgList &Args) {
22557330f729Sjoerg   GlobalDecl GD(Ctor, CtorType);
22567330f729Sjoerg   InlinedInheritingConstructorScope Scope(*this, GD);
22577330f729Sjoerg   ApplyInlineDebugLocation DebugScope(*this, GD);
22587330f729Sjoerg   RunCleanupsScope RunCleanups(*this);
22597330f729Sjoerg 
22607330f729Sjoerg   // Save the arguments to be passed to the inherited constructor.
22617330f729Sjoerg   CXXInheritedCtorInitExprArgs = Args;
22627330f729Sjoerg 
22637330f729Sjoerg   FunctionArgList Params;
22647330f729Sjoerg   QualType RetType = BuildFunctionArgList(CurGD, Params);
22657330f729Sjoerg   FnRetTy = RetType;
22667330f729Sjoerg 
22677330f729Sjoerg   // Insert any ABI-specific implicit constructor arguments.
22687330f729Sjoerg   CGM.getCXXABI().addImplicitConstructorArgs(*this, Ctor, CtorType,
22697330f729Sjoerg                                              ForVirtualBase, Delegating, Args);
22707330f729Sjoerg 
22717330f729Sjoerg   // Emit a simplified prolog. We only need to emit the implicit params.
22727330f729Sjoerg   assert(Args.size() >= Params.size() && "too few arguments for call");
22737330f729Sjoerg   for (unsigned I = 0, N = Args.size(); I != N; ++I) {
22747330f729Sjoerg     if (I < Params.size() && isa<ImplicitParamDecl>(Params[I])) {
22757330f729Sjoerg       const RValue &RV = Args[I].getRValue(*this);
22767330f729Sjoerg       assert(!RV.isComplex() && "complex indirect params not supported");
22777330f729Sjoerg       ParamValue Val = RV.isScalar()
22787330f729Sjoerg                            ? ParamValue::forDirect(RV.getScalarVal())
22797330f729Sjoerg                            : ParamValue::forIndirect(RV.getAggregateAddress());
22807330f729Sjoerg       EmitParmDecl(*Params[I], Val, I + 1);
22817330f729Sjoerg     }
22827330f729Sjoerg   }
22837330f729Sjoerg 
22847330f729Sjoerg   // Create a return value slot if the ABI implementation wants one.
22857330f729Sjoerg   // FIXME: This is dumb, we should ask the ABI not to try to set the return
22867330f729Sjoerg   // value instead.
22877330f729Sjoerg   if (!RetType->isVoidType())
22887330f729Sjoerg     ReturnValue = CreateIRTemp(RetType, "retval.inhctor");
22897330f729Sjoerg 
22907330f729Sjoerg   CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
22917330f729Sjoerg   CXXThisValue = CXXABIThisValue;
22927330f729Sjoerg 
22937330f729Sjoerg   // Directly emit the constructor initializers.
22947330f729Sjoerg   EmitCtorPrologue(Ctor, CtorType, Params);
22957330f729Sjoerg }
22967330f729Sjoerg 
EmitVTableAssumptionLoad(const VPtr & Vptr,Address This)22977330f729Sjoerg void CodeGenFunction::EmitVTableAssumptionLoad(const VPtr &Vptr, Address This) {
22987330f729Sjoerg   llvm::Value *VTableGlobal =
22997330f729Sjoerg       CGM.getCXXABI().getVTableAddressPoint(Vptr.Base, Vptr.VTableClass);
23007330f729Sjoerg   if (!VTableGlobal)
23017330f729Sjoerg     return;
23027330f729Sjoerg 
23037330f729Sjoerg   // We can just use the base offset in the complete class.
23047330f729Sjoerg   CharUnits NonVirtualOffset = Vptr.Base.getBaseOffset();
23057330f729Sjoerg 
23067330f729Sjoerg   if (!NonVirtualOffset.isZero())
23077330f729Sjoerg     This =
23087330f729Sjoerg         ApplyNonVirtualAndVirtualOffset(*this, This, NonVirtualOffset, nullptr,
23097330f729Sjoerg                                         Vptr.VTableClass, Vptr.NearestVBase);
23107330f729Sjoerg 
23117330f729Sjoerg   llvm::Value *VPtrValue =
23127330f729Sjoerg       GetVTablePtr(This, VTableGlobal->getType(), Vptr.VTableClass);
23137330f729Sjoerg   llvm::Value *Cmp =
23147330f729Sjoerg       Builder.CreateICmpEQ(VPtrValue, VTableGlobal, "cmp.vtables");
23157330f729Sjoerg   Builder.CreateAssumption(Cmp);
23167330f729Sjoerg }
23177330f729Sjoerg 
EmitVTableAssumptionLoads(const CXXRecordDecl * ClassDecl,Address This)23187330f729Sjoerg void CodeGenFunction::EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl,
23197330f729Sjoerg                                                 Address This) {
23207330f729Sjoerg   if (CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl))
23217330f729Sjoerg     for (const VPtr &Vptr : getVTablePointers(ClassDecl))
23227330f729Sjoerg       EmitVTableAssumptionLoad(Vptr, This);
23237330f729Sjoerg }
23247330f729Sjoerg 
23257330f729Sjoerg void
EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl * D,Address This,Address Src,const CXXConstructExpr * E)23267330f729Sjoerg CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
23277330f729Sjoerg                                                 Address This, Address Src,
23287330f729Sjoerg                                                 const CXXConstructExpr *E) {
23297330f729Sjoerg   const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
23307330f729Sjoerg 
23317330f729Sjoerg   CallArgList Args;
23327330f729Sjoerg 
23337330f729Sjoerg   // Push the this ptr.
23347330f729Sjoerg   Args.add(RValue::get(This.getPointer()), D->getThisType());
23357330f729Sjoerg 
23367330f729Sjoerg   // Push the src ptr.
23377330f729Sjoerg   QualType QT = *(FPT->param_type_begin());
23387330f729Sjoerg   llvm::Type *t = CGM.getTypes().ConvertType(QT);
23397330f729Sjoerg   Src = Builder.CreateBitCast(Src, t);
23407330f729Sjoerg   Args.add(RValue::get(Src.getPointer()), QT);
23417330f729Sjoerg 
23427330f729Sjoerg   // Skip over first argument (Src).
23437330f729Sjoerg   EmitCallArgs(Args, FPT, drop_begin(E->arguments(), 1), E->getConstructor(),
23447330f729Sjoerg                /*ParamsToSkip*/ 1);
23457330f729Sjoerg 
23467330f729Sjoerg   EmitCXXConstructorCall(D, Ctor_Complete, /*ForVirtualBase*/false,
23477330f729Sjoerg                          /*Delegating*/false, This, Args,
23487330f729Sjoerg                          AggValueSlot::MayOverlap, E->getExprLoc(),
23497330f729Sjoerg                          /*NewPointerIsChecked*/false);
23507330f729Sjoerg }
23517330f729Sjoerg 
23527330f729Sjoerg void
EmitDelegateCXXConstructorCall(const CXXConstructorDecl * Ctor,CXXCtorType CtorType,const FunctionArgList & Args,SourceLocation Loc)23537330f729Sjoerg CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
23547330f729Sjoerg                                                 CXXCtorType CtorType,
23557330f729Sjoerg                                                 const FunctionArgList &Args,
23567330f729Sjoerg                                                 SourceLocation Loc) {
23577330f729Sjoerg   CallArgList DelegateArgs;
23587330f729Sjoerg 
23597330f729Sjoerg   FunctionArgList::const_iterator I = Args.begin(), E = Args.end();
23607330f729Sjoerg   assert(I != E && "no parameters to constructor");
23617330f729Sjoerg 
23627330f729Sjoerg   // this
23637330f729Sjoerg   Address This = LoadCXXThisAddress();
23647330f729Sjoerg   DelegateArgs.add(RValue::get(This.getPointer()), (*I)->getType());
23657330f729Sjoerg   ++I;
23667330f729Sjoerg 
23677330f729Sjoerg   // FIXME: The location of the VTT parameter in the parameter list is
23687330f729Sjoerg   // specific to the Itanium ABI and shouldn't be hardcoded here.
23697330f729Sjoerg   if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {
23707330f729Sjoerg     assert(I != E && "cannot skip vtt parameter, already done with args");
23717330f729Sjoerg     assert((*I)->getType()->isPointerType() &&
23727330f729Sjoerg            "skipping parameter not of vtt type");
23737330f729Sjoerg     ++I;
23747330f729Sjoerg   }
23757330f729Sjoerg 
23767330f729Sjoerg   // Explicit arguments.
23777330f729Sjoerg   for (; I != E; ++I) {
23787330f729Sjoerg     const VarDecl *param = *I;
23797330f729Sjoerg     // FIXME: per-argument source location
23807330f729Sjoerg     EmitDelegateCallArg(DelegateArgs, param, Loc);
23817330f729Sjoerg   }
23827330f729Sjoerg 
23837330f729Sjoerg   EmitCXXConstructorCall(Ctor, CtorType, /*ForVirtualBase=*/false,
23847330f729Sjoerg                          /*Delegating=*/true, This, DelegateArgs,
23857330f729Sjoerg                          AggValueSlot::MayOverlap, Loc,
23867330f729Sjoerg                          /*NewPointerIsChecked=*/true);
23877330f729Sjoerg }
23887330f729Sjoerg 
23897330f729Sjoerg namespace {
23907330f729Sjoerg   struct CallDelegatingCtorDtor final : EHScopeStack::Cleanup {
23917330f729Sjoerg     const CXXDestructorDecl *Dtor;
23927330f729Sjoerg     Address Addr;
23937330f729Sjoerg     CXXDtorType Type;
23947330f729Sjoerg 
CallDelegatingCtorDtor__anonb72786c90911::CallDelegatingCtorDtor23957330f729Sjoerg     CallDelegatingCtorDtor(const CXXDestructorDecl *D, Address Addr,
23967330f729Sjoerg                            CXXDtorType Type)
23977330f729Sjoerg       : Dtor(D), Addr(Addr), Type(Type) {}
23987330f729Sjoerg 
Emit__anonb72786c90911::CallDelegatingCtorDtor23997330f729Sjoerg     void Emit(CodeGenFunction &CGF, Flags flags) override {
24007330f729Sjoerg       // We are calling the destructor from within the constructor.
24017330f729Sjoerg       // Therefore, "this" should have the expected type.
24027330f729Sjoerg       QualType ThisTy = Dtor->getThisObjectType();
24037330f729Sjoerg       CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false,
24047330f729Sjoerg                                 /*Delegating=*/true, Addr, ThisTy);
24057330f729Sjoerg     }
24067330f729Sjoerg   };
24077330f729Sjoerg } // end anonymous namespace
24087330f729Sjoerg 
24097330f729Sjoerg void
EmitDelegatingCXXConstructorCall(const CXXConstructorDecl * Ctor,const FunctionArgList & Args)24107330f729Sjoerg CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor,
24117330f729Sjoerg                                                   const FunctionArgList &Args) {
24127330f729Sjoerg   assert(Ctor->isDelegatingConstructor());
24137330f729Sjoerg 
24147330f729Sjoerg   Address ThisPtr = LoadCXXThisAddress();
24157330f729Sjoerg 
24167330f729Sjoerg   AggValueSlot AggSlot =
24177330f729Sjoerg     AggValueSlot::forAddr(ThisPtr, Qualifiers(),
24187330f729Sjoerg                           AggValueSlot::IsDestructed,
24197330f729Sjoerg                           AggValueSlot::DoesNotNeedGCBarriers,
24207330f729Sjoerg                           AggValueSlot::IsNotAliased,
24217330f729Sjoerg                           AggValueSlot::MayOverlap,
24227330f729Sjoerg                           AggValueSlot::IsNotZeroed,
24237330f729Sjoerg                           // Checks are made by the code that calls constructor.
24247330f729Sjoerg                           AggValueSlot::IsSanitizerChecked);
24257330f729Sjoerg 
24267330f729Sjoerg   EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot);
24277330f729Sjoerg 
24287330f729Sjoerg   const CXXRecordDecl *ClassDecl = Ctor->getParent();
24297330f729Sjoerg   if (CGM.getLangOpts().Exceptions && !ClassDecl->hasTrivialDestructor()) {
24307330f729Sjoerg     CXXDtorType Type =
24317330f729Sjoerg       CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base;
24327330f729Sjoerg 
24337330f729Sjoerg     EHStack.pushCleanup<CallDelegatingCtorDtor>(EHCleanup,
24347330f729Sjoerg                                                 ClassDecl->getDestructor(),
24357330f729Sjoerg                                                 ThisPtr, Type);
24367330f729Sjoerg   }
24377330f729Sjoerg }
24387330f729Sjoerg 
EmitCXXDestructorCall(const CXXDestructorDecl * DD,CXXDtorType Type,bool ForVirtualBase,bool Delegating,Address This,QualType ThisTy)24397330f729Sjoerg void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
24407330f729Sjoerg                                             CXXDtorType Type,
24417330f729Sjoerg                                             bool ForVirtualBase,
24427330f729Sjoerg                                             bool Delegating, Address This,
24437330f729Sjoerg                                             QualType ThisTy) {
24447330f729Sjoerg   CGM.getCXXABI().EmitDestructorCall(*this, DD, Type, ForVirtualBase,
24457330f729Sjoerg                                      Delegating, This, ThisTy);
24467330f729Sjoerg }
24477330f729Sjoerg 
24487330f729Sjoerg namespace {
24497330f729Sjoerg   struct CallLocalDtor final : EHScopeStack::Cleanup {
24507330f729Sjoerg     const CXXDestructorDecl *Dtor;
24517330f729Sjoerg     Address Addr;
24527330f729Sjoerg     QualType Ty;
24537330f729Sjoerg 
CallLocalDtor__anonb72786c90a11::CallLocalDtor24547330f729Sjoerg     CallLocalDtor(const CXXDestructorDecl *D, Address Addr, QualType Ty)
24557330f729Sjoerg         : Dtor(D), Addr(Addr), Ty(Ty) {}
24567330f729Sjoerg 
Emit__anonb72786c90a11::CallLocalDtor24577330f729Sjoerg     void Emit(CodeGenFunction &CGF, Flags flags) override {
24587330f729Sjoerg       CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
24597330f729Sjoerg                                 /*ForVirtualBase=*/false,
24607330f729Sjoerg                                 /*Delegating=*/false, Addr, Ty);
24617330f729Sjoerg     }
24627330f729Sjoerg   };
24637330f729Sjoerg } // end anonymous namespace
24647330f729Sjoerg 
PushDestructorCleanup(const CXXDestructorDecl * D,QualType T,Address Addr)24657330f729Sjoerg void CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D,
24667330f729Sjoerg                                             QualType T, Address Addr) {
24677330f729Sjoerg   EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr, T);
24687330f729Sjoerg }
24697330f729Sjoerg 
PushDestructorCleanup(QualType T,Address Addr)24707330f729Sjoerg void CodeGenFunction::PushDestructorCleanup(QualType T, Address Addr) {
24717330f729Sjoerg   CXXRecordDecl *ClassDecl = T->getAsCXXRecordDecl();
24727330f729Sjoerg   if (!ClassDecl) return;
24737330f729Sjoerg   if (ClassDecl->hasTrivialDestructor()) return;
24747330f729Sjoerg 
24757330f729Sjoerg   const CXXDestructorDecl *D = ClassDecl->getDestructor();
24767330f729Sjoerg   assert(D && D->isUsed() && "destructor not marked as used!");
24777330f729Sjoerg   PushDestructorCleanup(D, T, Addr);
24787330f729Sjoerg }
24797330f729Sjoerg 
InitializeVTablePointer(const VPtr & Vptr)24807330f729Sjoerg void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) {
24817330f729Sjoerg   // Compute the address point.
24827330f729Sjoerg   llvm::Value *VTableAddressPoint =
24837330f729Sjoerg       CGM.getCXXABI().getVTableAddressPointInStructor(
24847330f729Sjoerg           *this, Vptr.VTableClass, Vptr.Base, Vptr.NearestVBase);
24857330f729Sjoerg 
24867330f729Sjoerg   if (!VTableAddressPoint)
24877330f729Sjoerg     return;
24887330f729Sjoerg 
24897330f729Sjoerg   // Compute where to store the address point.
24907330f729Sjoerg   llvm::Value *VirtualOffset = nullptr;
24917330f729Sjoerg   CharUnits NonVirtualOffset = CharUnits::Zero();
24927330f729Sjoerg 
24937330f729Sjoerg   if (CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*this, Vptr)) {
24947330f729Sjoerg     // We need to use the virtual base offset offset because the virtual base
24957330f729Sjoerg     // might have a different offset in the most derived class.
24967330f729Sjoerg 
24977330f729Sjoerg     VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(
24987330f729Sjoerg         *this, LoadCXXThisAddress(), Vptr.VTableClass, Vptr.NearestVBase);
24997330f729Sjoerg     NonVirtualOffset = Vptr.OffsetFromNearestVBase;
25007330f729Sjoerg   } else {
25017330f729Sjoerg     // We can just use the base offset in the complete class.
25027330f729Sjoerg     NonVirtualOffset = Vptr.Base.getBaseOffset();
25037330f729Sjoerg   }
25047330f729Sjoerg 
25057330f729Sjoerg   // Apply the offsets.
25067330f729Sjoerg   Address VTableField = LoadCXXThisAddress();
25077330f729Sjoerg 
25087330f729Sjoerg   if (!NonVirtualOffset.isZero() || VirtualOffset)
25097330f729Sjoerg     VTableField = ApplyNonVirtualAndVirtualOffset(
25107330f729Sjoerg         *this, VTableField, NonVirtualOffset, VirtualOffset, Vptr.VTableClass,
25117330f729Sjoerg         Vptr.NearestVBase);
25127330f729Sjoerg 
25137330f729Sjoerg   // Finally, store the address point. Use the same LLVM types as the field to
25147330f729Sjoerg   // support optimization.
2515*e038c9c4Sjoerg   unsigned GlobalsAS = CGM.getDataLayout().getDefaultGlobalsAddressSpace();
2516*e038c9c4Sjoerg   unsigned ProgAS = CGM.getDataLayout().getProgramAddressSpace();
25177330f729Sjoerg   llvm::Type *VTablePtrTy =
25187330f729Sjoerg       llvm::FunctionType::get(CGM.Int32Ty, /*isVarArg=*/true)
2519*e038c9c4Sjoerg           ->getPointerTo(ProgAS)
2520*e038c9c4Sjoerg           ->getPointerTo(GlobalsAS);
2521*e038c9c4Sjoerg   VTableField = Builder.CreatePointerBitCastOrAddrSpaceCast(
2522*e038c9c4Sjoerg       VTableField, VTablePtrTy->getPointerTo(GlobalsAS));
2523*e038c9c4Sjoerg   VTableAddressPoint = Builder.CreatePointerBitCastOrAddrSpaceCast(
2524*e038c9c4Sjoerg       VTableAddressPoint, VTablePtrTy);
25257330f729Sjoerg 
25267330f729Sjoerg   llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField);
25277330f729Sjoerg   TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTablePtrTy);
25287330f729Sjoerg   CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
25297330f729Sjoerg   if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
25307330f729Sjoerg       CGM.getCodeGenOpts().StrictVTablePointers)
25317330f729Sjoerg     CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.VTableClass);
25327330f729Sjoerg }
25337330f729Sjoerg 
25347330f729Sjoerg CodeGenFunction::VPtrsVector
getVTablePointers(const CXXRecordDecl * VTableClass)25357330f729Sjoerg CodeGenFunction::getVTablePointers(const CXXRecordDecl *VTableClass) {
25367330f729Sjoerg   CodeGenFunction::VPtrsVector VPtrsResult;
25377330f729Sjoerg   VisitedVirtualBasesSetTy VBases;
25387330f729Sjoerg   getVTablePointers(BaseSubobject(VTableClass, CharUnits::Zero()),
25397330f729Sjoerg                     /*NearestVBase=*/nullptr,
25407330f729Sjoerg                     /*OffsetFromNearestVBase=*/CharUnits::Zero(),
25417330f729Sjoerg                     /*BaseIsNonVirtualPrimaryBase=*/false, VTableClass, VBases,
25427330f729Sjoerg                     VPtrsResult);
25437330f729Sjoerg   return VPtrsResult;
25447330f729Sjoerg }
25457330f729Sjoerg 
getVTablePointers(BaseSubobject Base,const CXXRecordDecl * NearestVBase,CharUnits OffsetFromNearestVBase,bool BaseIsNonVirtualPrimaryBase,const CXXRecordDecl * VTableClass,VisitedVirtualBasesSetTy & VBases,VPtrsVector & Vptrs)25467330f729Sjoerg void CodeGenFunction::getVTablePointers(BaseSubobject Base,
25477330f729Sjoerg                                         const CXXRecordDecl *NearestVBase,
25487330f729Sjoerg                                         CharUnits OffsetFromNearestVBase,
25497330f729Sjoerg                                         bool BaseIsNonVirtualPrimaryBase,
25507330f729Sjoerg                                         const CXXRecordDecl *VTableClass,
25517330f729Sjoerg                                         VisitedVirtualBasesSetTy &VBases,
25527330f729Sjoerg                                         VPtrsVector &Vptrs) {
25537330f729Sjoerg   // If this base is a non-virtual primary base the address point has already
25547330f729Sjoerg   // been set.
25557330f729Sjoerg   if (!BaseIsNonVirtualPrimaryBase) {
25567330f729Sjoerg     // Initialize the vtable pointer for this base.
25577330f729Sjoerg     VPtr Vptr = {Base, NearestVBase, OffsetFromNearestVBase, VTableClass};
25587330f729Sjoerg     Vptrs.push_back(Vptr);
25597330f729Sjoerg   }
25607330f729Sjoerg 
25617330f729Sjoerg   const CXXRecordDecl *RD = Base.getBase();
25627330f729Sjoerg 
25637330f729Sjoerg   // Traverse bases.
25647330f729Sjoerg   for (const auto &I : RD->bases()) {
25657330f729Sjoerg     auto *BaseDecl =
25667330f729Sjoerg         cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
25677330f729Sjoerg 
25687330f729Sjoerg     // Ignore classes without a vtable.
25697330f729Sjoerg     if (!BaseDecl->isDynamicClass())
25707330f729Sjoerg       continue;
25717330f729Sjoerg 
25727330f729Sjoerg     CharUnits BaseOffset;
25737330f729Sjoerg     CharUnits BaseOffsetFromNearestVBase;
25747330f729Sjoerg     bool BaseDeclIsNonVirtualPrimaryBase;
25757330f729Sjoerg 
25767330f729Sjoerg     if (I.isVirtual()) {
25777330f729Sjoerg       // Check if we've visited this virtual base before.
25787330f729Sjoerg       if (!VBases.insert(BaseDecl).second)
25797330f729Sjoerg         continue;
25807330f729Sjoerg 
25817330f729Sjoerg       const ASTRecordLayout &Layout =
25827330f729Sjoerg         getContext().getASTRecordLayout(VTableClass);
25837330f729Sjoerg 
25847330f729Sjoerg       BaseOffset = Layout.getVBaseClassOffset(BaseDecl);
25857330f729Sjoerg       BaseOffsetFromNearestVBase = CharUnits::Zero();
25867330f729Sjoerg       BaseDeclIsNonVirtualPrimaryBase = false;
25877330f729Sjoerg     } else {
25887330f729Sjoerg       const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
25897330f729Sjoerg 
25907330f729Sjoerg       BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl);
25917330f729Sjoerg       BaseOffsetFromNearestVBase =
25927330f729Sjoerg         OffsetFromNearestVBase + Layout.getBaseClassOffset(BaseDecl);
25937330f729Sjoerg       BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl;
25947330f729Sjoerg     }
25957330f729Sjoerg 
25967330f729Sjoerg     getVTablePointers(
25977330f729Sjoerg         BaseSubobject(BaseDecl, BaseOffset),
25987330f729Sjoerg         I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase,
25997330f729Sjoerg         BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs);
26007330f729Sjoerg   }
26017330f729Sjoerg }
26027330f729Sjoerg 
InitializeVTablePointers(const CXXRecordDecl * RD)26037330f729Sjoerg void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) {
26047330f729Sjoerg   // Ignore classes without a vtable.
26057330f729Sjoerg   if (!RD->isDynamicClass())
26067330f729Sjoerg     return;
26077330f729Sjoerg 
26087330f729Sjoerg   // Initialize the vtable pointers for this class and all of its bases.
26097330f729Sjoerg   if (CGM.getCXXABI().doStructorsInitializeVPtrs(RD))
26107330f729Sjoerg     for (const VPtr &Vptr : getVTablePointers(RD))
26117330f729Sjoerg       InitializeVTablePointer(Vptr);
26127330f729Sjoerg 
26137330f729Sjoerg   if (RD->getNumVBases())
26147330f729Sjoerg     CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, RD);
26157330f729Sjoerg }
26167330f729Sjoerg 
GetVTablePtr(Address This,llvm::Type * VTableTy,const CXXRecordDecl * RD)26177330f729Sjoerg llvm::Value *CodeGenFunction::GetVTablePtr(Address This,
26187330f729Sjoerg                                            llvm::Type *VTableTy,
26197330f729Sjoerg                                            const CXXRecordDecl *RD) {
26207330f729Sjoerg   Address VTablePtrSrc = Builder.CreateElementBitCast(This, VTableTy);
26217330f729Sjoerg   llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable");
26227330f729Sjoerg   TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy);
26237330f729Sjoerg   CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo);
26247330f729Sjoerg 
26257330f729Sjoerg   if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
26267330f729Sjoerg       CGM.getCodeGenOpts().StrictVTablePointers)
26277330f729Sjoerg     CGM.DecorateInstructionWithInvariantGroup(VTable, RD);
26287330f729Sjoerg 
26297330f729Sjoerg   return VTable;
26307330f729Sjoerg }
26317330f729Sjoerg 
26327330f729Sjoerg // If a class has a single non-virtual base and does not introduce or override
26337330f729Sjoerg // virtual member functions or fields, it will have the same layout as its base.
26347330f729Sjoerg // This function returns the least derived such class.
26357330f729Sjoerg //
26367330f729Sjoerg // Casting an instance of a base class to such a derived class is technically
26377330f729Sjoerg // undefined behavior, but it is a relatively common hack for introducing member
26387330f729Sjoerg // functions on class instances with specific properties (e.g. llvm::Operator)
26397330f729Sjoerg // that works under most compilers and should not have security implications, so
26407330f729Sjoerg // we allow it by default. It can be disabled with -fsanitize=cfi-cast-strict.
26417330f729Sjoerg static const CXXRecordDecl *
LeastDerivedClassWithSameLayout(const CXXRecordDecl * RD)26427330f729Sjoerg LeastDerivedClassWithSameLayout(const CXXRecordDecl *RD) {
26437330f729Sjoerg   if (!RD->field_empty())
26447330f729Sjoerg     return RD;
26457330f729Sjoerg 
26467330f729Sjoerg   if (RD->getNumVBases() != 0)
26477330f729Sjoerg     return RD;
26487330f729Sjoerg 
26497330f729Sjoerg   if (RD->getNumBases() != 1)
26507330f729Sjoerg     return RD;
26517330f729Sjoerg 
26527330f729Sjoerg   for (const CXXMethodDecl *MD : RD->methods()) {
26537330f729Sjoerg     if (MD->isVirtual()) {
26547330f729Sjoerg       // Virtual member functions are only ok if they are implicit destructors
26557330f729Sjoerg       // because the implicit destructor will have the same semantics as the
26567330f729Sjoerg       // base class's destructor if no fields are added.
26577330f729Sjoerg       if (isa<CXXDestructorDecl>(MD) && MD->isImplicit())
26587330f729Sjoerg         continue;
26597330f729Sjoerg       return RD;
26607330f729Sjoerg     }
26617330f729Sjoerg   }
26627330f729Sjoerg 
26637330f729Sjoerg   return LeastDerivedClassWithSameLayout(
26647330f729Sjoerg       RD->bases_begin()->getType()->getAsCXXRecordDecl());
26657330f729Sjoerg }
26667330f729Sjoerg 
EmitTypeMetadataCodeForVCall(const CXXRecordDecl * RD,llvm::Value * VTable,SourceLocation Loc)26677330f729Sjoerg void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD,
26687330f729Sjoerg                                                    llvm::Value *VTable,
26697330f729Sjoerg                                                    SourceLocation Loc) {
26707330f729Sjoerg   if (SanOpts.has(SanitizerKind::CFIVCall))
26717330f729Sjoerg     EmitVTablePtrCheckForCall(RD, VTable, CodeGenFunction::CFITCK_VCall, Loc);
26727330f729Sjoerg   else if (CGM.getCodeGenOpts().WholeProgramVTables &&
2673*e038c9c4Sjoerg            // Don't insert type test assumes if we are forcing public std
2674*e038c9c4Sjoerg            // visibility.
2675*e038c9c4Sjoerg            !CGM.HasLTOVisibilityPublicStd(RD)) {
26767330f729Sjoerg     llvm::Metadata *MD =
26777330f729Sjoerg         CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
26787330f729Sjoerg     llvm::Value *TypeId =
26797330f729Sjoerg         llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
26807330f729Sjoerg 
26817330f729Sjoerg     llvm::Value *CastedVTable = Builder.CreateBitCast(VTable, Int8PtrTy);
26827330f729Sjoerg     llvm::Value *TypeTest =
26837330f729Sjoerg         Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
26847330f729Sjoerg                            {CastedVTable, TypeId});
26857330f729Sjoerg     Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest);
26867330f729Sjoerg   }
26877330f729Sjoerg }
26887330f729Sjoerg 
EmitVTablePtrCheckForCall(const CXXRecordDecl * RD,llvm::Value * VTable,CFITypeCheckKind TCK,SourceLocation Loc)26897330f729Sjoerg void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
26907330f729Sjoerg                                                 llvm::Value *VTable,
26917330f729Sjoerg                                                 CFITypeCheckKind TCK,
26927330f729Sjoerg                                                 SourceLocation Loc) {
26937330f729Sjoerg   if (!SanOpts.has(SanitizerKind::CFICastStrict))
26947330f729Sjoerg     RD = LeastDerivedClassWithSameLayout(RD);
26957330f729Sjoerg 
26967330f729Sjoerg   EmitVTablePtrCheck(RD, VTable, TCK, Loc);
26977330f729Sjoerg }
26987330f729Sjoerg 
EmitVTablePtrCheckForCast(QualType T,llvm::Value * Derived,bool MayBeNull,CFITypeCheckKind TCK,SourceLocation Loc)26997330f729Sjoerg void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T,
27007330f729Sjoerg                                                 llvm::Value *Derived,
27017330f729Sjoerg                                                 bool MayBeNull,
27027330f729Sjoerg                                                 CFITypeCheckKind TCK,
27037330f729Sjoerg                                                 SourceLocation Loc) {
27047330f729Sjoerg   if (!getLangOpts().CPlusPlus)
27057330f729Sjoerg     return;
27067330f729Sjoerg 
27077330f729Sjoerg   auto *ClassTy = T->getAs<RecordType>();
27087330f729Sjoerg   if (!ClassTy)
27097330f729Sjoerg     return;
27107330f729Sjoerg 
27117330f729Sjoerg   const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassTy->getDecl());
27127330f729Sjoerg 
27137330f729Sjoerg   if (!ClassDecl->isCompleteDefinition() || !ClassDecl->isDynamicClass())
27147330f729Sjoerg     return;
27157330f729Sjoerg 
27167330f729Sjoerg   if (!SanOpts.has(SanitizerKind::CFICastStrict))
27177330f729Sjoerg     ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl);
27187330f729Sjoerg 
27197330f729Sjoerg   llvm::BasicBlock *ContBlock = nullptr;
27207330f729Sjoerg 
27217330f729Sjoerg   if (MayBeNull) {
27227330f729Sjoerg     llvm::Value *DerivedNotNull =
27237330f729Sjoerg         Builder.CreateIsNotNull(Derived, "cast.nonnull");
27247330f729Sjoerg 
27257330f729Sjoerg     llvm::BasicBlock *CheckBlock = createBasicBlock("cast.check");
27267330f729Sjoerg     ContBlock = createBasicBlock("cast.cont");
27277330f729Sjoerg 
27287330f729Sjoerg     Builder.CreateCondBr(DerivedNotNull, CheckBlock, ContBlock);
27297330f729Sjoerg 
27307330f729Sjoerg     EmitBlock(CheckBlock);
27317330f729Sjoerg   }
27327330f729Sjoerg 
27337330f729Sjoerg   llvm::Value *VTable;
27347330f729Sjoerg   std::tie(VTable, ClassDecl) = CGM.getCXXABI().LoadVTablePtr(
27357330f729Sjoerg       *this, Address(Derived, getPointerAlign()), ClassDecl);
27367330f729Sjoerg 
27377330f729Sjoerg   EmitVTablePtrCheck(ClassDecl, VTable, TCK, Loc);
27387330f729Sjoerg 
27397330f729Sjoerg   if (MayBeNull) {
27407330f729Sjoerg     Builder.CreateBr(ContBlock);
27417330f729Sjoerg     EmitBlock(ContBlock);
27427330f729Sjoerg   }
27437330f729Sjoerg }
27447330f729Sjoerg 
EmitVTablePtrCheck(const CXXRecordDecl * RD,llvm::Value * VTable,CFITypeCheckKind TCK,SourceLocation Loc)27457330f729Sjoerg void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
27467330f729Sjoerg                                          llvm::Value *VTable,
27477330f729Sjoerg                                          CFITypeCheckKind TCK,
27487330f729Sjoerg                                          SourceLocation Loc) {
27497330f729Sjoerg   if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
27507330f729Sjoerg       !CGM.HasHiddenLTOVisibility(RD))
27517330f729Sjoerg     return;
27527330f729Sjoerg 
27537330f729Sjoerg   SanitizerMask M;
27547330f729Sjoerg   llvm::SanitizerStatKind SSK;
27557330f729Sjoerg   switch (TCK) {
27567330f729Sjoerg   case CFITCK_VCall:
27577330f729Sjoerg     M = SanitizerKind::CFIVCall;
27587330f729Sjoerg     SSK = llvm::SanStat_CFI_VCall;
27597330f729Sjoerg     break;
27607330f729Sjoerg   case CFITCK_NVCall:
27617330f729Sjoerg     M = SanitizerKind::CFINVCall;
27627330f729Sjoerg     SSK = llvm::SanStat_CFI_NVCall;
27637330f729Sjoerg     break;
27647330f729Sjoerg   case CFITCK_DerivedCast:
27657330f729Sjoerg     M = SanitizerKind::CFIDerivedCast;
27667330f729Sjoerg     SSK = llvm::SanStat_CFI_DerivedCast;
27677330f729Sjoerg     break;
27687330f729Sjoerg   case CFITCK_UnrelatedCast:
27697330f729Sjoerg     M = SanitizerKind::CFIUnrelatedCast;
27707330f729Sjoerg     SSK = llvm::SanStat_CFI_UnrelatedCast;
27717330f729Sjoerg     break;
27727330f729Sjoerg   case CFITCK_ICall:
27737330f729Sjoerg   case CFITCK_NVMFCall:
27747330f729Sjoerg   case CFITCK_VMFCall:
27757330f729Sjoerg     llvm_unreachable("unexpected sanitizer kind");
27767330f729Sjoerg   }
27777330f729Sjoerg 
27787330f729Sjoerg   std::string TypeName = RD->getQualifiedNameAsString();
2779*e038c9c4Sjoerg   if (getContext().getNoSanitizeList().containsType(M, TypeName))
27807330f729Sjoerg     return;
27817330f729Sjoerg 
27827330f729Sjoerg   SanitizerScope SanScope(this);
27837330f729Sjoerg   EmitSanitizerStatReport(SSK);
27847330f729Sjoerg 
27857330f729Sjoerg   llvm::Metadata *MD =
27867330f729Sjoerg       CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
27877330f729Sjoerg   llvm::Value *TypeId = llvm::MetadataAsValue::get(getLLVMContext(), MD);
27887330f729Sjoerg 
27897330f729Sjoerg   llvm::Value *CastedVTable = Builder.CreateBitCast(VTable, Int8PtrTy);
27907330f729Sjoerg   llvm::Value *TypeTest = Builder.CreateCall(
27917330f729Sjoerg       CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, TypeId});
27927330f729Sjoerg 
27937330f729Sjoerg   llvm::Constant *StaticData[] = {
27947330f729Sjoerg       llvm::ConstantInt::get(Int8Ty, TCK),
27957330f729Sjoerg       EmitCheckSourceLocation(Loc),
27967330f729Sjoerg       EmitCheckTypeDescriptor(QualType(RD->getTypeForDecl(), 0)),
27977330f729Sjoerg   };
27987330f729Sjoerg 
27997330f729Sjoerg   auto CrossDsoTypeId = CGM.CreateCrossDsoCfiTypeId(MD);
28007330f729Sjoerg   if (CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) {
28017330f729Sjoerg     EmitCfiSlowPathCheck(M, TypeTest, CrossDsoTypeId, CastedVTable, StaticData);
28027330f729Sjoerg     return;
28037330f729Sjoerg   }
28047330f729Sjoerg 
28057330f729Sjoerg   if (CGM.getCodeGenOpts().SanitizeTrap.has(M)) {
2806*e038c9c4Sjoerg     EmitTrapCheck(TypeTest, SanitizerHandler::CFICheckFail);
28077330f729Sjoerg     return;
28087330f729Sjoerg   }
28097330f729Sjoerg 
28107330f729Sjoerg   llvm::Value *AllVtables = llvm::MetadataAsValue::get(
28117330f729Sjoerg       CGM.getLLVMContext(),
28127330f729Sjoerg       llvm::MDString::get(CGM.getLLVMContext(), "all-vtables"));
28137330f729Sjoerg   llvm::Value *ValidVtable = Builder.CreateCall(
28147330f729Sjoerg       CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, AllVtables});
28157330f729Sjoerg   EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail,
28167330f729Sjoerg             StaticData, {CastedVTable, ValidVtable});
28177330f729Sjoerg }
28187330f729Sjoerg 
ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl * RD)28197330f729Sjoerg bool CodeGenFunction::ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD) {
28207330f729Sjoerg   if (!CGM.getCodeGenOpts().WholeProgramVTables ||
28217330f729Sjoerg       !CGM.HasHiddenLTOVisibility(RD))
28227330f729Sjoerg     return false;
28237330f729Sjoerg 
28247330f729Sjoerg   if (CGM.getCodeGenOpts().VirtualFunctionElimination)
28257330f729Sjoerg     return true;
28267330f729Sjoerg 
28277330f729Sjoerg   if (!SanOpts.has(SanitizerKind::CFIVCall) ||
28287330f729Sjoerg       !CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIVCall))
28297330f729Sjoerg     return false;
28307330f729Sjoerg 
28317330f729Sjoerg   std::string TypeName = RD->getQualifiedNameAsString();
2832*e038c9c4Sjoerg   return !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall,
2833*e038c9c4Sjoerg                                                         TypeName);
28347330f729Sjoerg }
28357330f729Sjoerg 
EmitVTableTypeCheckedLoad(const CXXRecordDecl * RD,llvm::Value * VTable,uint64_t VTableByteOffset)28367330f729Sjoerg llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
28377330f729Sjoerg     const CXXRecordDecl *RD, llvm::Value *VTable, uint64_t VTableByteOffset) {
28387330f729Sjoerg   SanitizerScope SanScope(this);
28397330f729Sjoerg 
28407330f729Sjoerg   EmitSanitizerStatReport(llvm::SanStat_CFI_VCall);
28417330f729Sjoerg 
28427330f729Sjoerg   llvm::Metadata *MD =
28437330f729Sjoerg       CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
28447330f729Sjoerg   llvm::Value *TypeId = llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
28457330f729Sjoerg 
28467330f729Sjoerg   llvm::Value *CastedVTable = Builder.CreateBitCast(VTable, Int8PtrTy);
28477330f729Sjoerg   llvm::Value *CheckedLoad = Builder.CreateCall(
28487330f729Sjoerg       CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
28497330f729Sjoerg       {CastedVTable, llvm::ConstantInt::get(Int32Ty, VTableByteOffset),
28507330f729Sjoerg        TypeId});
28517330f729Sjoerg   llvm::Value *CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
28527330f729Sjoerg 
28537330f729Sjoerg   std::string TypeName = RD->getQualifiedNameAsString();
28547330f729Sjoerg   if (SanOpts.has(SanitizerKind::CFIVCall) &&
2855*e038c9c4Sjoerg       !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall,
2856*e038c9c4Sjoerg                                                      TypeName)) {
28577330f729Sjoerg     EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIVCall),
28587330f729Sjoerg               SanitizerHandler::CFICheckFail, {}, {});
28597330f729Sjoerg   }
28607330f729Sjoerg 
28617330f729Sjoerg   return Builder.CreateBitCast(
28627330f729Sjoerg       Builder.CreateExtractValue(CheckedLoad, 0),
28637330f729Sjoerg       cast<llvm::PointerType>(VTable->getType())->getElementType());
28647330f729Sjoerg }
28657330f729Sjoerg 
EmitForwardingCallToLambda(const CXXMethodDecl * callOperator,CallArgList & callArgs)28667330f729Sjoerg void CodeGenFunction::EmitForwardingCallToLambda(
28677330f729Sjoerg                                       const CXXMethodDecl *callOperator,
28687330f729Sjoerg                                       CallArgList &callArgs) {
28697330f729Sjoerg   // Get the address of the call operator.
28707330f729Sjoerg   const CGFunctionInfo &calleeFnInfo =
28717330f729Sjoerg     CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
28727330f729Sjoerg   llvm::Constant *calleePtr =
28737330f729Sjoerg     CGM.GetAddrOfFunction(GlobalDecl(callOperator),
28747330f729Sjoerg                           CGM.getTypes().GetFunctionType(calleeFnInfo));
28757330f729Sjoerg 
28767330f729Sjoerg   // Prepare the return slot.
28777330f729Sjoerg   const FunctionProtoType *FPT =
28787330f729Sjoerg     callOperator->getType()->castAs<FunctionProtoType>();
28797330f729Sjoerg   QualType resultType = FPT->getReturnType();
28807330f729Sjoerg   ReturnValueSlot returnSlot;
28817330f729Sjoerg   if (!resultType->isVoidType() &&
28827330f729Sjoerg       calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect &&
28837330f729Sjoerg       !hasScalarEvaluationKind(calleeFnInfo.getReturnType()))
2884*e038c9c4Sjoerg     returnSlot =
2885*e038c9c4Sjoerg         ReturnValueSlot(ReturnValue, resultType.isVolatileQualified(),
2886*e038c9c4Sjoerg                         /*IsUnused=*/false, /*IsExternallyDestructed=*/true);
28877330f729Sjoerg 
28887330f729Sjoerg   // We don't need to separately arrange the call arguments because
28897330f729Sjoerg   // the call can't be variadic anyway --- it's impossible to forward
28907330f729Sjoerg   // variadic arguments.
28917330f729Sjoerg 
28927330f729Sjoerg   // Now emit our call.
28937330f729Sjoerg   auto callee = CGCallee::forDirect(calleePtr, GlobalDecl(callOperator));
28947330f729Sjoerg   RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs);
28957330f729Sjoerg 
28967330f729Sjoerg   // If necessary, copy the returned value into the slot.
28977330f729Sjoerg   if (!resultType->isVoidType() && returnSlot.isNull()) {
28987330f729Sjoerg     if (getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType()) {
28997330f729Sjoerg       RV = RValue::get(EmitARCRetainAutoreleasedReturnValue(RV.getScalarVal()));
29007330f729Sjoerg     }
29017330f729Sjoerg     EmitReturnOfRValue(RV, resultType);
29027330f729Sjoerg   } else
29037330f729Sjoerg     EmitBranchThroughCleanup(ReturnBlock);
29047330f729Sjoerg }
29057330f729Sjoerg 
EmitLambdaBlockInvokeBody()29067330f729Sjoerg void CodeGenFunction::EmitLambdaBlockInvokeBody() {
29077330f729Sjoerg   const BlockDecl *BD = BlockInfo->getBlockDecl();
29087330f729Sjoerg   const VarDecl *variable = BD->capture_begin()->getVariable();
29097330f729Sjoerg   const CXXRecordDecl *Lambda = variable->getType()->getAsCXXRecordDecl();
29107330f729Sjoerg   const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator();
29117330f729Sjoerg 
29127330f729Sjoerg   if (CallOp->isVariadic()) {
29137330f729Sjoerg     // FIXME: Making this work correctly is nasty because it requires either
29147330f729Sjoerg     // cloning the body of the call operator or making the call operator
29157330f729Sjoerg     // forward.
29167330f729Sjoerg     CGM.ErrorUnsupported(CurCodeDecl, "lambda conversion to variadic function");
29177330f729Sjoerg     return;
29187330f729Sjoerg   }
29197330f729Sjoerg 
29207330f729Sjoerg   // Start building arguments for forwarding call
29217330f729Sjoerg   CallArgList CallArgs;
29227330f729Sjoerg 
29237330f729Sjoerg   QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda));
29247330f729Sjoerg   Address ThisPtr = GetAddrOfBlockDecl(variable);
29257330f729Sjoerg   CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType);
29267330f729Sjoerg 
29277330f729Sjoerg   // Add the rest of the parameters.
29287330f729Sjoerg   for (auto param : BD->parameters())
29297330f729Sjoerg     EmitDelegateCallArg(CallArgs, param, param->getBeginLoc());
29307330f729Sjoerg 
29317330f729Sjoerg   assert(!Lambda->isGenericLambda() &&
29327330f729Sjoerg             "generic lambda interconversion to block not implemented");
29337330f729Sjoerg   EmitForwardingCallToLambda(CallOp, CallArgs);
29347330f729Sjoerg }
29357330f729Sjoerg 
EmitLambdaDelegatingInvokeBody(const CXXMethodDecl * MD)29367330f729Sjoerg void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) {
29377330f729Sjoerg   const CXXRecordDecl *Lambda = MD->getParent();
29387330f729Sjoerg 
29397330f729Sjoerg   // Start building arguments for forwarding call
29407330f729Sjoerg   CallArgList CallArgs;
29417330f729Sjoerg 
29427330f729Sjoerg   QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda));
29437330f729Sjoerg   llvm::Value *ThisPtr = llvm::UndefValue::get(getTypes().ConvertType(ThisType));
29447330f729Sjoerg   CallArgs.add(RValue::get(ThisPtr), ThisType);
29457330f729Sjoerg 
29467330f729Sjoerg   // Add the rest of the parameters.
29477330f729Sjoerg   for (auto Param : MD->parameters())
29487330f729Sjoerg     EmitDelegateCallArg(CallArgs, Param, Param->getBeginLoc());
29497330f729Sjoerg 
29507330f729Sjoerg   const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator();
29517330f729Sjoerg   // For a generic lambda, find the corresponding call operator specialization
29527330f729Sjoerg   // to which the call to the static-invoker shall be forwarded.
29537330f729Sjoerg   if (Lambda->isGenericLambda()) {
29547330f729Sjoerg     assert(MD->isFunctionTemplateSpecialization());
29557330f729Sjoerg     const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs();
29567330f729Sjoerg     FunctionTemplateDecl *CallOpTemplate = CallOp->getDescribedFunctionTemplate();
29577330f729Sjoerg     void *InsertPos = nullptr;
29587330f729Sjoerg     FunctionDecl *CorrespondingCallOpSpecialization =
29597330f729Sjoerg         CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
29607330f729Sjoerg     assert(CorrespondingCallOpSpecialization);
29617330f729Sjoerg     CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
29627330f729Sjoerg   }
29637330f729Sjoerg   EmitForwardingCallToLambda(CallOp, CallArgs);
29647330f729Sjoerg }
29657330f729Sjoerg 
EmitLambdaStaticInvokeBody(const CXXMethodDecl * MD)29667330f729Sjoerg void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) {
29677330f729Sjoerg   if (MD->isVariadic()) {
29687330f729Sjoerg     // FIXME: Making this work correctly is nasty because it requires either
29697330f729Sjoerg     // cloning the body of the call operator or making the call operator forward.
29707330f729Sjoerg     CGM.ErrorUnsupported(MD, "lambda conversion to variadic function");
29717330f729Sjoerg     return;
29727330f729Sjoerg   }
29737330f729Sjoerg 
29747330f729Sjoerg   EmitLambdaDelegatingInvokeBody(MD);
29757330f729Sjoerg }
2976