10b57cec5SDimitry Andric //===--- CGClass.cpp - Emit LLVM Code for C++ classes -----------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This contains code dealing with C++ code generation of classes 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "CGBlocks.h" 140b57cec5SDimitry Andric #include "CGCXXABI.h" 150b57cec5SDimitry Andric #include "CGDebugInfo.h" 160b57cec5SDimitry Andric #include "CGRecordLayout.h" 170b57cec5SDimitry Andric #include "CodeGenFunction.h" 180b57cec5SDimitry Andric #include "TargetInfo.h" 19480093f4SDimitry Andric #include "clang/AST/Attr.h" 200b57cec5SDimitry Andric #include "clang/AST/CXXInheritance.h" 21e8d8bef9SDimitry Andric #include "clang/AST/CharUnits.h" 220b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h" 230b57cec5SDimitry Andric #include "clang/AST/EvaluatedExprVisitor.h" 240b57cec5SDimitry Andric #include "clang/AST/RecordLayout.h" 250b57cec5SDimitry Andric #include "clang/AST/StmtCXX.h" 260b57cec5SDimitry Andric #include "clang/Basic/CodeGenOptions.h" 270b57cec5SDimitry Andric #include "clang/Basic/TargetBuiltins.h" 280b57cec5SDimitry Andric #include "clang/CodeGen/CGFunctionInfo.h" 290b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h" 300b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 310b57cec5SDimitry Andric #include "llvm/Transforms/Utils/SanitizerStats.h" 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric using namespace clang; 340b57cec5SDimitry Andric using namespace CodeGen; 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric /// Return the best known alignment for an unknown pointer to a 370b57cec5SDimitry Andric /// particular class. 380b57cec5SDimitry Andric CharUnits CodeGenModule::getClassPointerAlignment(const CXXRecordDecl *RD) { 395ffd83dbSDimitry Andric if (!RD->hasDefinition()) 400b57cec5SDimitry Andric return CharUnits::One(); // Hopefully won't be used anywhere. 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric auto &layout = getContext().getASTRecordLayout(RD); 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric // If the class is final, then we know that the pointer points to an 450b57cec5SDimitry Andric // object of that type and can use the full alignment. 465ffd83dbSDimitry Andric if (RD->isEffectivelyFinal()) 470b57cec5SDimitry Andric return layout.getAlignment(); 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric // Otherwise, we have to assume it could be a subclass. 500b57cec5SDimitry Andric return layout.getNonVirtualAlignment(); 510b57cec5SDimitry Andric } 525ffd83dbSDimitry Andric 535ffd83dbSDimitry Andric /// Return the smallest possible amount of storage that might be allocated 545ffd83dbSDimitry Andric /// starting from the beginning of an object of a particular class. 555ffd83dbSDimitry Andric /// 565ffd83dbSDimitry Andric /// This may be smaller than sizeof(RD) if RD has virtual base classes. 575ffd83dbSDimitry Andric CharUnits CodeGenModule::getMinimumClassObjectSize(const CXXRecordDecl *RD) { 585ffd83dbSDimitry Andric if (!RD->hasDefinition()) 595ffd83dbSDimitry Andric return CharUnits::One(); 605ffd83dbSDimitry Andric 615ffd83dbSDimitry Andric auto &layout = getContext().getASTRecordLayout(RD); 625ffd83dbSDimitry Andric 635ffd83dbSDimitry Andric // If the class is final, then we know that the pointer points to an 645ffd83dbSDimitry Andric // object of that type and can use the full alignment. 655ffd83dbSDimitry Andric if (RD->isEffectivelyFinal()) 665ffd83dbSDimitry Andric return layout.getSize(); 675ffd83dbSDimitry Andric 685ffd83dbSDimitry Andric // Otherwise, we have to assume it could be a subclass. 695ffd83dbSDimitry Andric return std::max(layout.getNonVirtualSize(), CharUnits::One()); 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric /// Return the best known alignment for a pointer to a virtual base, 730b57cec5SDimitry Andric /// given the alignment of a pointer to the derived class. 740b57cec5SDimitry Andric CharUnits CodeGenModule::getVBaseAlignment(CharUnits actualDerivedAlign, 750b57cec5SDimitry Andric const CXXRecordDecl *derivedClass, 760b57cec5SDimitry Andric const CXXRecordDecl *vbaseClass) { 770b57cec5SDimitry Andric // The basic idea here is that an underaligned derived pointer might 780b57cec5SDimitry Andric // indicate an underaligned base pointer. 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric assert(vbaseClass->isCompleteDefinition()); 810b57cec5SDimitry Andric auto &baseLayout = getContext().getASTRecordLayout(vbaseClass); 820b57cec5SDimitry Andric CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment(); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric return getDynamicOffsetAlignment(actualDerivedAlign, derivedClass, 850b57cec5SDimitry Andric expectedVBaseAlign); 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric CharUnits 890b57cec5SDimitry Andric CodeGenModule::getDynamicOffsetAlignment(CharUnits actualBaseAlign, 900b57cec5SDimitry Andric const CXXRecordDecl *baseDecl, 910b57cec5SDimitry Andric CharUnits expectedTargetAlign) { 920b57cec5SDimitry Andric // If the base is an incomplete type (which is, alas, possible with 930b57cec5SDimitry Andric // member pointers), be pessimistic. 940b57cec5SDimitry Andric if (!baseDecl->isCompleteDefinition()) 950b57cec5SDimitry Andric return std::min(actualBaseAlign, expectedTargetAlign); 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric auto &baseLayout = getContext().getASTRecordLayout(baseDecl); 980b57cec5SDimitry Andric CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment(); 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric // If the class is properly aligned, assume the target offset is, too. 1010b57cec5SDimitry Andric // 1020b57cec5SDimitry Andric // This actually isn't necessarily the right thing to do --- if the 1030b57cec5SDimitry Andric // class is a complete object, but it's only properly aligned for a 1040b57cec5SDimitry Andric // base subobject, then the alignments of things relative to it are 1050b57cec5SDimitry Andric // probably off as well. (Note that this requires the alignment of 1060b57cec5SDimitry Andric // the target to be greater than the NV alignment of the derived 1070b57cec5SDimitry Andric // class.) 1080b57cec5SDimitry Andric // 1090b57cec5SDimitry Andric // However, our approach to this kind of under-alignment can only 1100b57cec5SDimitry Andric // ever be best effort; after all, we're never going to propagate 1110b57cec5SDimitry Andric // alignments through variables or parameters. Note, in particular, 1120b57cec5SDimitry Andric // that constructing a polymorphic type in an address that's less 1130b57cec5SDimitry Andric // than pointer-aligned will generally trap in the constructor, 1140b57cec5SDimitry Andric // unless we someday add some sort of attribute to change the 1150b57cec5SDimitry Andric // assumed alignment of 'this'. So our goal here is pretty much 1160b57cec5SDimitry Andric // just to allow the user to explicitly say that a pointer is 1170b57cec5SDimitry Andric // under-aligned and then safely access its fields and vtables. 1180b57cec5SDimitry Andric if (actualBaseAlign >= expectedBaseAlign) { 1190b57cec5SDimitry Andric return expectedTargetAlign; 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric // Otherwise, we might be offset by an arbitrary multiple of the 1230b57cec5SDimitry Andric // actual alignment. The correct adjustment is to take the min of 1240b57cec5SDimitry Andric // the two alignments. 1250b57cec5SDimitry Andric return std::min(actualBaseAlign, expectedTargetAlign); 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric Address CodeGenFunction::LoadCXXThisAddress() { 1290b57cec5SDimitry Andric assert(CurFuncDecl && "loading 'this' without a func declaration?"); 1300eae32dcSDimitry Andric auto *MD = cast<CXXMethodDecl>(CurFuncDecl); 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric // Lazily compute CXXThisAlignment. 1330b57cec5SDimitry Andric if (CXXThisAlignment.isZero()) { 1340b57cec5SDimitry Andric // Just use the best known alignment for the parent. 1350b57cec5SDimitry Andric // TODO: if we're currently emitting a complete-object ctor/dtor, 1360b57cec5SDimitry Andric // we can always use the complete-object alignment. 1370eae32dcSDimitry Andric CXXThisAlignment = CGM.getClassPointerAlignment(MD->getParent()); 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric 1400eae32dcSDimitry Andric llvm::Type *Ty = ConvertType(MD->getThisType()->getPointeeType()); 1410eae32dcSDimitry Andric return Address(LoadCXXThis(), Ty, CXXThisAlignment); 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric /// Emit the address of a field using a member data pointer. 1450b57cec5SDimitry Andric /// 1460b57cec5SDimitry Andric /// \param E Only used for emergency diagnostics 1470b57cec5SDimitry Andric Address 1480b57cec5SDimitry Andric CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base, 1490b57cec5SDimitry Andric llvm::Value *memberPtr, 1500b57cec5SDimitry Andric const MemberPointerType *memberPtrType, 1510b57cec5SDimitry Andric LValueBaseInfo *BaseInfo, 1520b57cec5SDimitry Andric TBAAAccessInfo *TBAAInfo) { 1530b57cec5SDimitry Andric // Ask the ABI to compute the actual address. 1540b57cec5SDimitry Andric llvm::Value *ptr = 1550b57cec5SDimitry Andric CGM.getCXXABI().EmitMemberDataPointerAddress(*this, E, base, 1560b57cec5SDimitry Andric memberPtr, memberPtrType); 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric QualType memberType = memberPtrType->getPointeeType(); 1595ffd83dbSDimitry Andric CharUnits memberAlign = 1605ffd83dbSDimitry Andric CGM.getNaturalTypeAlignment(memberType, BaseInfo, TBAAInfo); 1610b57cec5SDimitry Andric memberAlign = 1620b57cec5SDimitry Andric CGM.getDynamicOffsetAlignment(base.getAlignment(), 1630b57cec5SDimitry Andric memberPtrType->getClass()->getAsCXXRecordDecl(), 1640b57cec5SDimitry Andric memberAlign); 1650b57cec5SDimitry Andric return Address(ptr, memberAlign); 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric CharUnits CodeGenModule::computeNonVirtualBaseClassOffset( 1690b57cec5SDimitry Andric const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, 1700b57cec5SDimitry Andric CastExpr::path_const_iterator End) { 1710b57cec5SDimitry Andric CharUnits Offset = CharUnits::Zero(); 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric const ASTContext &Context = getContext(); 1740b57cec5SDimitry Andric const CXXRecordDecl *RD = DerivedClass; 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric for (CastExpr::path_const_iterator I = Start; I != End; ++I) { 1770b57cec5SDimitry Andric const CXXBaseSpecifier *Base = *I; 1780b57cec5SDimitry Andric assert(!Base->isVirtual() && "Should not see virtual bases here!"); 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric // Get the layout. 1810b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1820b57cec5SDimitry Andric 183a7dea167SDimitry Andric const auto *BaseDecl = 184a7dea167SDimitry Andric cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl()); 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric // Add the offset. 1870b57cec5SDimitry Andric Offset += Layout.getBaseClassOffset(BaseDecl); 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric RD = BaseDecl; 1900b57cec5SDimitry Andric } 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric return Offset; 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric llvm::Constant * 1960b57cec5SDimitry Andric CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, 1970b57cec5SDimitry Andric CastExpr::path_const_iterator PathBegin, 1980b57cec5SDimitry Andric CastExpr::path_const_iterator PathEnd) { 1990b57cec5SDimitry Andric assert(PathBegin != PathEnd && "Base path should not be empty!"); 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric CharUnits Offset = 2020b57cec5SDimitry Andric computeNonVirtualBaseClassOffset(ClassDecl, PathBegin, PathEnd); 2030b57cec5SDimitry Andric if (Offset.isZero()) 2040b57cec5SDimitry Andric return nullptr; 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric llvm::Type *PtrDiffTy = 2070b57cec5SDimitry Andric Types.ConvertType(getContext().getPointerDiffType()); 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity()); 2100b57cec5SDimitry Andric } 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric /// Gets the address of a direct base class within a complete object. 2130b57cec5SDimitry Andric /// This should only be used for (1) non-virtual bases or (2) virtual bases 2140b57cec5SDimitry Andric /// when the type is known to be complete (e.g. in complete destructors). 2150b57cec5SDimitry Andric /// 2160b57cec5SDimitry Andric /// The object pointed to by 'This' is assumed to be non-null. 2170b57cec5SDimitry Andric Address 2180b57cec5SDimitry Andric CodeGenFunction::GetAddressOfDirectBaseInCompleteClass(Address This, 2190b57cec5SDimitry Andric const CXXRecordDecl *Derived, 2200b57cec5SDimitry Andric const CXXRecordDecl *Base, 2210b57cec5SDimitry Andric bool BaseIsVirtual) { 2220b57cec5SDimitry Andric // 'this' must be a pointer (in some address space) to Derived. 2230b57cec5SDimitry Andric assert(This.getElementType() == ConvertType(Derived)); 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric // Compute the offset of the virtual base. 2260b57cec5SDimitry Andric CharUnits Offset; 2270b57cec5SDimitry Andric const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); 2280b57cec5SDimitry Andric if (BaseIsVirtual) 2290b57cec5SDimitry Andric Offset = Layout.getVBaseClassOffset(Base); 2300b57cec5SDimitry Andric else 2310b57cec5SDimitry Andric Offset = Layout.getBaseClassOffset(Base); 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric // Shift and cast down to the base type. 2340b57cec5SDimitry Andric // TODO: for complete types, this should be possible with a GEP. 2350b57cec5SDimitry Andric Address V = This; 2360b57cec5SDimitry Andric if (!Offset.isZero()) { 2370b57cec5SDimitry Andric V = Builder.CreateElementBitCast(V, Int8Ty); 2380b57cec5SDimitry Andric V = Builder.CreateConstInBoundsByteGEP(V, Offset); 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric V = Builder.CreateElementBitCast(V, ConvertType(Base)); 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric return V; 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric static Address 2460b57cec5SDimitry Andric ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, 2470b57cec5SDimitry Andric CharUnits nonVirtualOffset, 2480b57cec5SDimitry Andric llvm::Value *virtualOffset, 2490b57cec5SDimitry Andric const CXXRecordDecl *derivedClass, 2500b57cec5SDimitry Andric const CXXRecordDecl *nearestVBase) { 2510b57cec5SDimitry Andric // Assert that we have something to do. 2520b57cec5SDimitry Andric assert(!nonVirtualOffset.isZero() || virtualOffset != nullptr); 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric // Compute the offset from the static and dynamic components. 2550b57cec5SDimitry Andric llvm::Value *baseOffset; 2560b57cec5SDimitry Andric if (!nonVirtualOffset.isZero()) { 2575ffd83dbSDimitry Andric llvm::Type *OffsetType = 2585ffd83dbSDimitry Andric (CGF.CGM.getTarget().getCXXABI().isItaniumFamily() && 2595ffd83dbSDimitry Andric CGF.CGM.getItaniumVTableContext().isRelativeLayout()) 2605ffd83dbSDimitry Andric ? CGF.Int32Ty 2615ffd83dbSDimitry Andric : CGF.PtrDiffTy; 2625ffd83dbSDimitry Andric baseOffset = 2635ffd83dbSDimitry Andric llvm::ConstantInt::get(OffsetType, nonVirtualOffset.getQuantity()); 2640b57cec5SDimitry Andric if (virtualOffset) { 2650b57cec5SDimitry Andric baseOffset = CGF.Builder.CreateAdd(virtualOffset, baseOffset); 2660b57cec5SDimitry Andric } 2670b57cec5SDimitry Andric } else { 2680b57cec5SDimitry Andric baseOffset = virtualOffset; 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric // Apply the base offset. 2720b57cec5SDimitry Andric llvm::Value *ptr = addr.getPointer(); 273a7dea167SDimitry Andric unsigned AddrSpace = ptr->getType()->getPointerAddressSpace(); 274a7dea167SDimitry Andric ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8Ty->getPointerTo(AddrSpace)); 275fe6060f1SDimitry Andric ptr = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, ptr, baseOffset, "add.ptr"); 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric // If we have a virtual component, the alignment of the result will 2780b57cec5SDimitry Andric // be relative only to the known alignment of that vbase. 2790b57cec5SDimitry Andric CharUnits alignment; 2800b57cec5SDimitry Andric if (virtualOffset) { 2810b57cec5SDimitry Andric assert(nearestVBase && "virtual offset without vbase?"); 2820b57cec5SDimitry Andric alignment = CGF.CGM.getVBaseAlignment(addr.getAlignment(), 2830b57cec5SDimitry Andric derivedClass, nearestVBase); 2840b57cec5SDimitry Andric } else { 2850b57cec5SDimitry Andric alignment = addr.getAlignment(); 2860b57cec5SDimitry Andric } 2870b57cec5SDimitry Andric alignment = alignment.alignmentAtOffset(nonVirtualOffset); 2880b57cec5SDimitry Andric 2890eae32dcSDimitry Andric return Address(ptr, CGF.Int8Ty, alignment); 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric Address CodeGenFunction::GetAddressOfBaseClass( 2930b57cec5SDimitry Andric Address Value, const CXXRecordDecl *Derived, 2940b57cec5SDimitry Andric CastExpr::path_const_iterator PathBegin, 2950b57cec5SDimitry Andric CastExpr::path_const_iterator PathEnd, bool NullCheckValue, 2960b57cec5SDimitry Andric SourceLocation Loc) { 2970b57cec5SDimitry Andric assert(PathBegin != PathEnd && "Base path should not be empty!"); 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric CastExpr::path_const_iterator Start = PathBegin; 3000b57cec5SDimitry Andric const CXXRecordDecl *VBase = nullptr; 3010b57cec5SDimitry Andric 3020b57cec5SDimitry Andric // Sema has done some convenient canonicalization here: if the 3030b57cec5SDimitry Andric // access path involved any virtual steps, the conversion path will 3040b57cec5SDimitry Andric // *start* with a step down to the correct virtual base subobject, 3050b57cec5SDimitry Andric // and hence will not require any further steps. 3060b57cec5SDimitry Andric if ((*Start)->isVirtual()) { 307a7dea167SDimitry Andric VBase = cast<CXXRecordDecl>( 308a7dea167SDimitry Andric (*Start)->getType()->castAs<RecordType>()->getDecl()); 3090b57cec5SDimitry Andric ++Start; 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric // Compute the static offset of the ultimate destination within its 3130b57cec5SDimitry Andric // allocating subobject (the virtual base, if there is one, or else 3140b57cec5SDimitry Andric // the "complete" object that we see). 3150b57cec5SDimitry Andric CharUnits NonVirtualOffset = CGM.computeNonVirtualBaseClassOffset( 3160b57cec5SDimitry Andric VBase ? VBase : Derived, Start, PathEnd); 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric // If there's a virtual step, we can sometimes "devirtualize" it. 3190b57cec5SDimitry Andric // For now, that's limited to when the derived type is final. 3200b57cec5SDimitry Andric // TODO: "devirtualize" this for accesses to known-complete objects. 3210b57cec5SDimitry Andric if (VBase && Derived->hasAttr<FinalAttr>()) { 3220b57cec5SDimitry Andric const ASTRecordLayout &layout = getContext().getASTRecordLayout(Derived); 3230b57cec5SDimitry Andric CharUnits vBaseOffset = layout.getVBaseClassOffset(VBase); 3240b57cec5SDimitry Andric NonVirtualOffset += vBaseOffset; 3250b57cec5SDimitry Andric VBase = nullptr; // we no longer have a virtual step 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric // Get the base pointer type. 3290eae32dcSDimitry Andric llvm::Type *BaseValueTy = ConvertType((PathEnd[-1])->getType()); 3300b57cec5SDimitry Andric llvm::Type *BasePtrTy = 3310eae32dcSDimitry Andric BaseValueTy->getPointerTo(Value.getType()->getPointerAddressSpace()); 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric QualType DerivedTy = getContext().getRecordType(Derived); 3340b57cec5SDimitry Andric CharUnits DerivedAlign = CGM.getClassPointerAlignment(Derived); 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric // If the static offset is zero and we don't have a virtual step, 3370b57cec5SDimitry Andric // just do a bitcast; null checks are unnecessary. 3380b57cec5SDimitry Andric if (NonVirtualOffset.isZero() && !VBase) { 3390b57cec5SDimitry Andric if (sanitizePerformTypeCheck()) { 3400b57cec5SDimitry Andric SanitizerSet SkippedChecks; 3410b57cec5SDimitry Andric SkippedChecks.set(SanitizerKind::Null, !NullCheckValue); 3420b57cec5SDimitry Andric EmitTypeCheck(TCK_Upcast, Loc, Value.getPointer(), 3430b57cec5SDimitry Andric DerivedTy, DerivedAlign, SkippedChecks); 3440b57cec5SDimitry Andric } 3450eae32dcSDimitry Andric return Builder.CreateElementBitCast(Value, BaseValueTy); 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric llvm::BasicBlock *origBB = nullptr; 3490b57cec5SDimitry Andric llvm::BasicBlock *endBB = nullptr; 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric // Skip over the offset (and the vtable load) if we're supposed to 3520b57cec5SDimitry Andric // null-check the pointer. 3530b57cec5SDimitry Andric if (NullCheckValue) { 3540b57cec5SDimitry Andric origBB = Builder.GetInsertBlock(); 3550b57cec5SDimitry Andric llvm::BasicBlock *notNullBB = createBasicBlock("cast.notnull"); 3560b57cec5SDimitry Andric endBB = createBasicBlock("cast.end"); 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric llvm::Value *isNull = Builder.CreateIsNull(Value.getPointer()); 3590b57cec5SDimitry Andric Builder.CreateCondBr(isNull, endBB, notNullBB); 3600b57cec5SDimitry Andric EmitBlock(notNullBB); 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric if (sanitizePerformTypeCheck()) { 3640b57cec5SDimitry Andric SanitizerSet SkippedChecks; 3650b57cec5SDimitry Andric SkippedChecks.set(SanitizerKind::Null, true); 3660b57cec5SDimitry Andric EmitTypeCheck(VBase ? TCK_UpcastToVirtualBase : TCK_Upcast, Loc, 3670b57cec5SDimitry Andric Value.getPointer(), DerivedTy, DerivedAlign, SkippedChecks); 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric // Compute the virtual offset. 3710b57cec5SDimitry Andric llvm::Value *VirtualOffset = nullptr; 3720b57cec5SDimitry Andric if (VBase) { 3730b57cec5SDimitry Andric VirtualOffset = 3740b57cec5SDimitry Andric CGM.getCXXABI().GetVirtualBaseClassOffset(*this, Value, Derived, VBase); 3750b57cec5SDimitry Andric } 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric // Apply both offsets. 3780b57cec5SDimitry Andric Value = ApplyNonVirtualAndVirtualOffset(*this, Value, NonVirtualOffset, 3790b57cec5SDimitry Andric VirtualOffset, Derived, VBase); 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric // Cast to the destination type. 3820eae32dcSDimitry Andric Value = Builder.CreateElementBitCast(Value, BaseValueTy); 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric // Build a phi if we needed a null check. 3850b57cec5SDimitry Andric if (NullCheckValue) { 3860b57cec5SDimitry Andric llvm::BasicBlock *notNullBB = Builder.GetInsertBlock(); 3870b57cec5SDimitry Andric Builder.CreateBr(endBB); 3880b57cec5SDimitry Andric EmitBlock(endBB); 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric llvm::PHINode *PHI = Builder.CreatePHI(BasePtrTy, 2, "cast.result"); 3910b57cec5SDimitry Andric PHI->addIncoming(Value.getPointer(), notNullBB); 3920b57cec5SDimitry Andric PHI->addIncoming(llvm::Constant::getNullValue(BasePtrTy), origBB); 39304eeddc0SDimitry Andric Value = Value.withPointer(PHI); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric return Value; 3970b57cec5SDimitry Andric } 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric Address 4000b57cec5SDimitry Andric CodeGenFunction::GetAddressOfDerivedClass(Address BaseAddr, 4010b57cec5SDimitry Andric const CXXRecordDecl *Derived, 4020b57cec5SDimitry Andric CastExpr::path_const_iterator PathBegin, 4030b57cec5SDimitry Andric CastExpr::path_const_iterator PathEnd, 4040b57cec5SDimitry Andric bool NullCheckValue) { 4050b57cec5SDimitry Andric assert(PathBegin != PathEnd && "Base path should not be empty!"); 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric QualType DerivedTy = 4080b57cec5SDimitry Andric getContext().getCanonicalType(getContext().getTagDeclType(Derived)); 4090eae32dcSDimitry Andric unsigned AddrSpace = BaseAddr.getAddressSpace(); 4100eae32dcSDimitry Andric llvm::Type *DerivedValueTy = ConvertType(DerivedTy); 4110eae32dcSDimitry Andric llvm::Type *DerivedPtrTy = DerivedValueTy->getPointerTo(AddrSpace); 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric llvm::Value *NonVirtualOffset = 4140b57cec5SDimitry Andric CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd); 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric if (!NonVirtualOffset) { 4170b57cec5SDimitry Andric // No offset, we can just cast back. 4180eae32dcSDimitry Andric return Builder.CreateElementBitCast(BaseAddr, DerivedValueTy); 4190b57cec5SDimitry Andric } 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric llvm::BasicBlock *CastNull = nullptr; 4220b57cec5SDimitry Andric llvm::BasicBlock *CastNotNull = nullptr; 4230b57cec5SDimitry Andric llvm::BasicBlock *CastEnd = nullptr; 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric if (NullCheckValue) { 4260b57cec5SDimitry Andric CastNull = createBasicBlock("cast.null"); 4270b57cec5SDimitry Andric CastNotNull = createBasicBlock("cast.notnull"); 4280b57cec5SDimitry Andric CastEnd = createBasicBlock("cast.end"); 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric llvm::Value *IsNull = Builder.CreateIsNull(BaseAddr.getPointer()); 4310b57cec5SDimitry Andric Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 4320b57cec5SDimitry Andric EmitBlock(CastNotNull); 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric // Apply the offset. 4360b57cec5SDimitry Andric llvm::Value *Value = Builder.CreateBitCast(BaseAddr.getPointer(), Int8PtrTy); 437fe6060f1SDimitry Andric Value = Builder.CreateInBoundsGEP( 438fe6060f1SDimitry Andric Int8Ty, Value, Builder.CreateNeg(NonVirtualOffset), "sub.ptr"); 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andric // Just cast. 4410b57cec5SDimitry Andric Value = Builder.CreateBitCast(Value, DerivedPtrTy); 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric // Produce a PHI if we had a null-check. 4440b57cec5SDimitry Andric if (NullCheckValue) { 4450b57cec5SDimitry Andric Builder.CreateBr(CastEnd); 4460b57cec5SDimitry Andric EmitBlock(CastNull); 4470b57cec5SDimitry Andric Builder.CreateBr(CastEnd); 4480b57cec5SDimitry Andric EmitBlock(CastEnd); 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); 4510b57cec5SDimitry Andric PHI->addIncoming(Value, CastNotNull); 4520b57cec5SDimitry Andric PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull); 4530b57cec5SDimitry Andric Value = PHI; 4540b57cec5SDimitry Andric } 4550b57cec5SDimitry Andric 4560eae32dcSDimitry Andric return Address(Value, DerivedValueTy, CGM.getClassPointerAlignment(Derived)); 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD, 4600b57cec5SDimitry Andric bool ForVirtualBase, 4610b57cec5SDimitry Andric bool Delegating) { 4620b57cec5SDimitry Andric if (!CGM.getCXXABI().NeedsVTTParameter(GD)) { 4630b57cec5SDimitry Andric // This constructor/destructor does not need a VTT parameter. 4640b57cec5SDimitry Andric return nullptr; 4650b57cec5SDimitry Andric } 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric const CXXRecordDecl *RD = cast<CXXMethodDecl>(CurCodeDecl)->getParent(); 4680b57cec5SDimitry Andric const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric uint64_t SubVTTIndex; 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric if (Delegating) { 4730b57cec5SDimitry Andric // If this is a delegating constructor call, just load the VTT. 4740b57cec5SDimitry Andric return LoadCXXVTT(); 4750b57cec5SDimitry Andric } else if (RD == Base) { 4760b57cec5SDimitry Andric // If the record matches the base, this is the complete ctor/dtor 4770b57cec5SDimitry Andric // variant calling the base variant in a class with virtual bases. 4780b57cec5SDimitry Andric assert(!CGM.getCXXABI().NeedsVTTParameter(CurGD) && 4790b57cec5SDimitry Andric "doing no-op VTT offset in base dtor/ctor?"); 4800b57cec5SDimitry Andric assert(!ForVirtualBase && "Can't have same class as virtual base!"); 4810b57cec5SDimitry Andric SubVTTIndex = 0; 4820b57cec5SDimitry Andric } else { 4830b57cec5SDimitry Andric const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 4840b57cec5SDimitry Andric CharUnits BaseOffset = ForVirtualBase ? 4850b57cec5SDimitry Andric Layout.getVBaseClassOffset(Base) : 4860b57cec5SDimitry Andric Layout.getBaseClassOffset(Base); 4870b57cec5SDimitry Andric 4880b57cec5SDimitry Andric SubVTTIndex = 4890b57cec5SDimitry Andric CGM.getVTables().getSubVTTIndex(RD, BaseSubobject(Base, BaseOffset)); 4900b57cec5SDimitry Andric assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!"); 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) { 4940b57cec5SDimitry Andric // A VTT parameter was passed to the constructor, use it. 495fe6060f1SDimitry Andric llvm::Value *VTT = LoadCXXVTT(); 496fe6060f1SDimitry Andric return Builder.CreateConstInBoundsGEP1_64(VoidPtrTy, VTT, SubVTTIndex); 4970b57cec5SDimitry Andric } else { 4980b57cec5SDimitry Andric // We're the complete constructor, so get the VTT by name. 499fe6060f1SDimitry Andric llvm::GlobalValue *VTT = CGM.getVTables().GetAddrOfVTT(RD); 500fe6060f1SDimitry Andric return Builder.CreateConstInBoundsGEP2_64( 501fe6060f1SDimitry Andric VTT->getValueType(), VTT, 0, SubVTTIndex); 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric } 5040b57cec5SDimitry Andric 5050b57cec5SDimitry Andric namespace { 5060b57cec5SDimitry Andric /// Call the destructor for a direct base class. 5070b57cec5SDimitry Andric struct CallBaseDtor final : EHScopeStack::Cleanup { 5080b57cec5SDimitry Andric const CXXRecordDecl *BaseClass; 5090b57cec5SDimitry Andric bool BaseIsVirtual; 5100b57cec5SDimitry Andric CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual) 5110b57cec5SDimitry Andric : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {} 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 5140b57cec5SDimitry Andric const CXXRecordDecl *DerivedClass = 5150b57cec5SDimitry Andric cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent(); 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric const CXXDestructorDecl *D = BaseClass->getDestructor(); 5180b57cec5SDimitry Andric // We are already inside a destructor, so presumably the object being 5190b57cec5SDimitry Andric // destroyed should have the expected type. 5200b57cec5SDimitry Andric QualType ThisTy = D->getThisObjectType(); 5210b57cec5SDimitry Andric Address Addr = 5220b57cec5SDimitry Andric CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThisAddress(), 5230b57cec5SDimitry Andric DerivedClass, BaseClass, 5240b57cec5SDimitry Andric BaseIsVirtual); 5250b57cec5SDimitry Andric CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual, 5260b57cec5SDimitry Andric /*Delegating=*/false, Addr, ThisTy); 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric }; 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric /// A visitor which checks whether an initializer uses 'this' in a 5310b57cec5SDimitry Andric /// way which requires the vtable to be properly set. 5320b57cec5SDimitry Andric struct DynamicThisUseChecker : ConstEvaluatedExprVisitor<DynamicThisUseChecker> { 5330b57cec5SDimitry Andric typedef ConstEvaluatedExprVisitor<DynamicThisUseChecker> super; 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric bool UsesThis; 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric DynamicThisUseChecker(const ASTContext &C) : super(C), UsesThis(false) {} 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andric // Black-list all explicit and implicit references to 'this'. 5400b57cec5SDimitry Andric // 5410b57cec5SDimitry Andric // Do we need to worry about external references to 'this' derived 5420b57cec5SDimitry Andric // from arbitrary code? If so, then anything which runs arbitrary 5430b57cec5SDimitry Andric // external code might potentially access the vtable. 5440b57cec5SDimitry Andric void VisitCXXThisExpr(const CXXThisExpr *E) { UsesThis = true; } 5450b57cec5SDimitry Andric }; 5460b57cec5SDimitry Andric } // end anonymous namespace 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) { 5490b57cec5SDimitry Andric DynamicThisUseChecker Checker(C); 5500b57cec5SDimitry Andric Checker.Visit(Init); 5510b57cec5SDimitry Andric return Checker.UsesThis; 5520b57cec5SDimitry Andric } 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric static void EmitBaseInitializer(CodeGenFunction &CGF, 5550b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl, 5560b57cec5SDimitry Andric CXXCtorInitializer *BaseInit) { 5570b57cec5SDimitry Andric assert(BaseInit->isBaseInitializer() && 5580b57cec5SDimitry Andric "Must have base initializer!"); 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric Address ThisPtr = CGF.LoadCXXThisAddress(); 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andric const Type *BaseType = BaseInit->getBaseClass(); 563a7dea167SDimitry Andric const auto *BaseClassDecl = 564a7dea167SDimitry Andric cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl()); 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric bool isBaseVirtual = BaseInit->isBaseVirtual(); 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric // If the initializer for the base (other than the constructor 5690b57cec5SDimitry Andric // itself) accesses 'this' in any way, we need to initialize the 5700b57cec5SDimitry Andric // vtables. 5710b57cec5SDimitry Andric if (BaseInitializerUsesThis(CGF.getContext(), BaseInit->getInit())) 5720b57cec5SDimitry Andric CGF.InitializeVTablePointers(ClassDecl); 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric // We can pretend to be a complete class because it only matters for 5750b57cec5SDimitry Andric // virtual bases, and we only do virtual bases for complete ctors. 5760b57cec5SDimitry Andric Address V = 5770b57cec5SDimitry Andric CGF.GetAddressOfDirectBaseInCompleteClass(ThisPtr, ClassDecl, 5780b57cec5SDimitry Andric BaseClassDecl, 5790b57cec5SDimitry Andric isBaseVirtual); 5800b57cec5SDimitry Andric AggValueSlot AggSlot = 5810b57cec5SDimitry Andric AggValueSlot::forAddr( 5820b57cec5SDimitry Andric V, Qualifiers(), 5830b57cec5SDimitry Andric AggValueSlot::IsDestructed, 5840b57cec5SDimitry Andric AggValueSlot::DoesNotNeedGCBarriers, 5850b57cec5SDimitry Andric AggValueSlot::IsNotAliased, 5860b57cec5SDimitry Andric CGF.getOverlapForBaseInit(ClassDecl, BaseClassDecl, isBaseVirtual)); 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric if (CGF.CGM.getLangOpts().Exceptions && 5910b57cec5SDimitry Andric !BaseClassDecl->hasTrivialDestructor()) 5920b57cec5SDimitry Andric CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl, 5930b57cec5SDimitry Andric isBaseVirtual); 5940b57cec5SDimitry Andric } 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric static bool isMemcpyEquivalentSpecialMember(const CXXMethodDecl *D) { 5970b57cec5SDimitry Andric auto *CD = dyn_cast<CXXConstructorDecl>(D); 5980b57cec5SDimitry Andric if (!(CD && CD->isCopyOrMoveConstructor()) && 5990b57cec5SDimitry Andric !D->isCopyAssignmentOperator() && !D->isMoveAssignmentOperator()) 6000b57cec5SDimitry Andric return false; 6010b57cec5SDimitry Andric 6020b57cec5SDimitry Andric // We can emit a memcpy for a trivial copy or move constructor/assignment. 6030b57cec5SDimitry Andric if (D->isTrivial() && !D->getParent()->mayInsertExtraPadding()) 6040b57cec5SDimitry Andric return true; 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric // We *must* emit a memcpy for a defaulted union copy or move op. 6070b57cec5SDimitry Andric if (D->getParent()->isUnion() && D->isDefaulted()) 6080b57cec5SDimitry Andric return true; 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric return false; 6110b57cec5SDimitry Andric } 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric static void EmitLValueForAnyFieldInitialization(CodeGenFunction &CGF, 6140b57cec5SDimitry Andric CXXCtorInitializer *MemberInit, 6150b57cec5SDimitry Andric LValue &LHS) { 6160b57cec5SDimitry Andric FieldDecl *Field = MemberInit->getAnyMember(); 6170b57cec5SDimitry Andric if (MemberInit->isIndirectMemberInitializer()) { 6180b57cec5SDimitry Andric // If we are initializing an anonymous union field, drill down to the field. 6190b57cec5SDimitry Andric IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember(); 6200b57cec5SDimitry Andric for (const auto *I : IndirectField->chain()) 6210b57cec5SDimitry Andric LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(I)); 6220b57cec5SDimitry Andric } else { 6230b57cec5SDimitry Andric LHS = CGF.EmitLValueForFieldInitialization(LHS, Field); 6240b57cec5SDimitry Andric } 6250b57cec5SDimitry Andric } 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric static void EmitMemberInitializer(CodeGenFunction &CGF, 6280b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl, 6290b57cec5SDimitry Andric CXXCtorInitializer *MemberInit, 6300b57cec5SDimitry Andric const CXXConstructorDecl *Constructor, 6310b57cec5SDimitry Andric FunctionArgList &Args) { 6320b57cec5SDimitry Andric ApplyDebugLocation Loc(CGF, MemberInit->getSourceLocation()); 6330b57cec5SDimitry Andric assert(MemberInit->isAnyMemberInitializer() && 6340b57cec5SDimitry Andric "Must have member initializer!"); 6350b57cec5SDimitry Andric assert(MemberInit->getInit() && "Must have initializer!"); 6360b57cec5SDimitry Andric 6370b57cec5SDimitry Andric // non-static data member initializers. 6380b57cec5SDimitry Andric FieldDecl *Field = MemberInit->getAnyMember(); 6390b57cec5SDimitry Andric QualType FieldType = Field->getType(); 6400b57cec5SDimitry Andric 6410b57cec5SDimitry Andric llvm::Value *ThisPtr = CGF.LoadCXXThis(); 6420b57cec5SDimitry Andric QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 6430b57cec5SDimitry Andric LValue LHS; 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric // If a base constructor is being emitted, create an LValue that has the 6460b57cec5SDimitry Andric // non-virtual alignment. 6470b57cec5SDimitry Andric if (CGF.CurGD.getCtorType() == Ctor_Base) 6480b57cec5SDimitry Andric LHS = CGF.MakeNaturalAlignPointeeAddrLValue(ThisPtr, RecordTy); 6490b57cec5SDimitry Andric else 6500b57cec5SDimitry Andric LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric EmitLValueForAnyFieldInitialization(CGF, MemberInit, LHS); 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric // Special case: if we are in a copy or move constructor, and we are copying 6550b57cec5SDimitry Andric // an array of PODs or classes with trivial copy constructors, ignore the 6560b57cec5SDimitry Andric // AST and perform the copy we know is equivalent. 6570b57cec5SDimitry Andric // FIXME: This is hacky at best... if we had a bit more explicit information 6580b57cec5SDimitry Andric // in the AST, we could generalize it more easily. 6590b57cec5SDimitry Andric const ConstantArrayType *Array 6600b57cec5SDimitry Andric = CGF.getContext().getAsConstantArrayType(FieldType); 6610b57cec5SDimitry Andric if (Array && Constructor->isDefaulted() && 6620b57cec5SDimitry Andric Constructor->isCopyOrMoveConstructor()) { 6630b57cec5SDimitry Andric QualType BaseElementTy = CGF.getContext().getBaseElementType(Array); 6640b57cec5SDimitry Andric CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); 6650b57cec5SDimitry Andric if (BaseElementTy.isPODType(CGF.getContext()) || 6660b57cec5SDimitry Andric (CE && isMemcpyEquivalentSpecialMember(CE->getConstructor()))) { 6670b57cec5SDimitry Andric unsigned SrcArgIndex = 6680b57cec5SDimitry Andric CGF.CGM.getCXXABI().getSrcArgforCopyCtor(Constructor, Args); 6690b57cec5SDimitry Andric llvm::Value *SrcPtr 6700b57cec5SDimitry Andric = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex])); 6710b57cec5SDimitry Andric LValue ThisRHSLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); 6720b57cec5SDimitry Andric LValue Src = CGF.EmitLValueForFieldInitialization(ThisRHSLV, Field); 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric // Copy the aggregate. 6750b57cec5SDimitry Andric CGF.EmitAggregateCopy(LHS, Src, FieldType, CGF.getOverlapForFieldInit(Field), 6760b57cec5SDimitry Andric LHS.isVolatileQualified()); 6770b57cec5SDimitry Andric // Ensure that we destroy the objects if an exception is thrown later in 6780b57cec5SDimitry Andric // the constructor. 6790b57cec5SDimitry Andric QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 6800b57cec5SDimitry Andric if (CGF.needsEHCleanup(dtorKind)) 681480093f4SDimitry Andric CGF.pushEHDestroy(dtorKind, LHS.getAddress(CGF), FieldType); 6820b57cec5SDimitry Andric return; 6830b57cec5SDimitry Andric } 6840b57cec5SDimitry Andric } 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit()); 6870b57cec5SDimitry Andric } 6880b57cec5SDimitry Andric 6890b57cec5SDimitry Andric void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS, 6900b57cec5SDimitry Andric Expr *Init) { 6910b57cec5SDimitry Andric QualType FieldType = Field->getType(); 6920b57cec5SDimitry Andric switch (getEvaluationKind(FieldType)) { 6930b57cec5SDimitry Andric case TEK_Scalar: 6940b57cec5SDimitry Andric if (LHS.isSimple()) { 6950b57cec5SDimitry Andric EmitExprAsInit(Init, Field, LHS, false); 6960b57cec5SDimitry Andric } else { 6970b57cec5SDimitry Andric RValue RHS = RValue::get(EmitScalarExpr(Init)); 6980b57cec5SDimitry Andric EmitStoreThroughLValue(RHS, LHS); 6990b57cec5SDimitry Andric } 7000b57cec5SDimitry Andric break; 7010b57cec5SDimitry Andric case TEK_Complex: 7020b57cec5SDimitry Andric EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true); 7030b57cec5SDimitry Andric break; 7040b57cec5SDimitry Andric case TEK_Aggregate: { 705480093f4SDimitry Andric AggValueSlot Slot = AggValueSlot::forLValue( 706480093f4SDimitry Andric LHS, *this, AggValueSlot::IsDestructed, 707480093f4SDimitry Andric AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, 708480093f4SDimitry Andric getOverlapForFieldInit(Field), AggValueSlot::IsNotZeroed, 7090b57cec5SDimitry Andric // Checks are made by the code that calls constructor. 7100b57cec5SDimitry Andric AggValueSlot::IsSanitizerChecked); 7110b57cec5SDimitry Andric EmitAggExpr(Init, Slot); 7120b57cec5SDimitry Andric break; 7130b57cec5SDimitry Andric } 7140b57cec5SDimitry Andric } 7150b57cec5SDimitry Andric 7160b57cec5SDimitry Andric // Ensure that we destroy this object if an exception is thrown 7170b57cec5SDimitry Andric // later in the constructor. 7180b57cec5SDimitry Andric QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 7190b57cec5SDimitry Andric if (needsEHCleanup(dtorKind)) 720480093f4SDimitry Andric pushEHDestroy(dtorKind, LHS.getAddress(*this), FieldType); 7210b57cec5SDimitry Andric } 7220b57cec5SDimitry Andric 7230b57cec5SDimitry Andric /// Checks whether the given constructor is a valid subject for the 7240b57cec5SDimitry Andric /// complete-to-base constructor delegation optimization, i.e. 7250b57cec5SDimitry Andric /// emitting the complete constructor as a simple call to the base 7260b57cec5SDimitry Andric /// constructor. 7270b57cec5SDimitry Andric bool CodeGenFunction::IsConstructorDelegationValid( 7280b57cec5SDimitry Andric const CXXConstructorDecl *Ctor) { 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andric // Currently we disable the optimization for classes with virtual 7310b57cec5SDimitry Andric // bases because (1) the addresses of parameter variables need to be 7320b57cec5SDimitry Andric // consistent across all initializers but (2) the delegate function 7330b57cec5SDimitry Andric // call necessarily creates a second copy of the parameter variable. 7340b57cec5SDimitry Andric // 7350b57cec5SDimitry Andric // The limiting example (purely theoretical AFAIK): 7360b57cec5SDimitry Andric // struct A { A(int &c) { c++; } }; 7370b57cec5SDimitry Andric // struct B : virtual A { 7380b57cec5SDimitry Andric // B(int count) : A(count) { printf("%d\n", count); } 7390b57cec5SDimitry Andric // }; 7400b57cec5SDimitry Andric // ...although even this example could in principle be emitted as a 7410b57cec5SDimitry Andric // delegation since the address of the parameter doesn't escape. 7420b57cec5SDimitry Andric if (Ctor->getParent()->getNumVBases()) { 7430b57cec5SDimitry Andric // TODO: white-list trivial vbase initializers. This case wouldn't 7440b57cec5SDimitry Andric // be subject to the restrictions below. 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andric // TODO: white-list cases where: 7470b57cec5SDimitry Andric // - there are no non-reference parameters to the constructor 7480b57cec5SDimitry Andric // - the initializers don't access any non-reference parameters 7490b57cec5SDimitry Andric // - the initializers don't take the address of non-reference 7500b57cec5SDimitry Andric // parameters 7510b57cec5SDimitry Andric // - etc. 7520b57cec5SDimitry Andric // If we ever add any of the above cases, remember that: 7535ffd83dbSDimitry Andric // - function-try-blocks will always exclude this optimization 7540b57cec5SDimitry Andric // - we need to perform the constructor prologue and cleanup in 7550b57cec5SDimitry Andric // EmitConstructorBody. 7560b57cec5SDimitry Andric 7570b57cec5SDimitry Andric return false; 7580b57cec5SDimitry Andric } 7590b57cec5SDimitry Andric 7600b57cec5SDimitry Andric // We also disable the optimization for variadic functions because 7610b57cec5SDimitry Andric // it's impossible to "re-pass" varargs. 762a7dea167SDimitry Andric if (Ctor->getType()->castAs<FunctionProtoType>()->isVariadic()) 7630b57cec5SDimitry Andric return false; 7640b57cec5SDimitry Andric 7650b57cec5SDimitry Andric // FIXME: Decide if we can do a delegation of a delegating constructor. 7660b57cec5SDimitry Andric if (Ctor->isDelegatingConstructor()) 7670b57cec5SDimitry Andric return false; 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric return true; 7700b57cec5SDimitry Andric } 7710b57cec5SDimitry Andric 7720b57cec5SDimitry Andric // Emit code in ctor (Prologue==true) or dtor (Prologue==false) 7730b57cec5SDimitry Andric // to poison the extra field paddings inserted under 7740b57cec5SDimitry Andric // -fsanitize-address-field-padding=1|2. 7750b57cec5SDimitry Andric void CodeGenFunction::EmitAsanPrologueOrEpilogue(bool Prologue) { 7760b57cec5SDimitry Andric ASTContext &Context = getContext(); 7770b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = 7780b57cec5SDimitry Andric Prologue ? cast<CXXConstructorDecl>(CurGD.getDecl())->getParent() 7790b57cec5SDimitry Andric : cast<CXXDestructorDecl>(CurGD.getDecl())->getParent(); 7800b57cec5SDimitry Andric if (!ClassDecl->mayInsertExtraPadding()) return; 7810b57cec5SDimitry Andric 7820b57cec5SDimitry Andric struct SizeAndOffset { 7830b57cec5SDimitry Andric uint64_t Size; 7840b57cec5SDimitry Andric uint64_t Offset; 7850b57cec5SDimitry Andric }; 7860b57cec5SDimitry Andric 7870b57cec5SDimitry Andric unsigned PtrSize = CGM.getDataLayout().getPointerSizeInBits(); 7880b57cec5SDimitry Andric const ASTRecordLayout &Info = Context.getASTRecordLayout(ClassDecl); 7890b57cec5SDimitry Andric 7900b57cec5SDimitry Andric // Populate sizes and offsets of fields. 7910b57cec5SDimitry Andric SmallVector<SizeAndOffset, 16> SSV(Info.getFieldCount()); 7920b57cec5SDimitry Andric for (unsigned i = 0, e = Info.getFieldCount(); i != e; ++i) 7930b57cec5SDimitry Andric SSV[i].Offset = 7940b57cec5SDimitry Andric Context.toCharUnitsFromBits(Info.getFieldOffset(i)).getQuantity(); 7950b57cec5SDimitry Andric 7960b57cec5SDimitry Andric size_t NumFields = 0; 7970b57cec5SDimitry Andric for (const auto *Field : ClassDecl->fields()) { 7980b57cec5SDimitry Andric const FieldDecl *D = Field; 799e8d8bef9SDimitry Andric auto FieldInfo = Context.getTypeInfoInChars(D->getType()); 800e8d8bef9SDimitry Andric CharUnits FieldSize = FieldInfo.Width; 8010b57cec5SDimitry Andric assert(NumFields < SSV.size()); 8020b57cec5SDimitry Andric SSV[NumFields].Size = D->isBitField() ? 0 : FieldSize.getQuantity(); 8030b57cec5SDimitry Andric NumFields++; 8040b57cec5SDimitry Andric } 8050b57cec5SDimitry Andric assert(NumFields == SSV.size()); 8060b57cec5SDimitry Andric if (SSV.size() <= 1) return; 8070b57cec5SDimitry Andric 8080b57cec5SDimitry Andric // We will insert calls to __asan_* run-time functions. 8090b57cec5SDimitry Andric // LLVM AddressSanitizer pass may decide to inline them later. 8100b57cec5SDimitry Andric llvm::Type *Args[2] = {IntPtrTy, IntPtrTy}; 8110b57cec5SDimitry Andric llvm::FunctionType *FTy = 8120b57cec5SDimitry Andric llvm::FunctionType::get(CGM.VoidTy, Args, false); 8130b57cec5SDimitry Andric llvm::FunctionCallee F = CGM.CreateRuntimeFunction( 8140b57cec5SDimitry Andric FTy, Prologue ? "__asan_poison_intra_object_redzone" 8150b57cec5SDimitry Andric : "__asan_unpoison_intra_object_redzone"); 8160b57cec5SDimitry Andric 8170b57cec5SDimitry Andric llvm::Value *ThisPtr = LoadCXXThis(); 8180b57cec5SDimitry Andric ThisPtr = Builder.CreatePtrToInt(ThisPtr, IntPtrTy); 8190b57cec5SDimitry Andric uint64_t TypeSize = Info.getNonVirtualSize().getQuantity(); 8200b57cec5SDimitry Andric // For each field check if it has sufficient padding, 8210b57cec5SDimitry Andric // if so (un)poison it with a call. 8220b57cec5SDimitry Andric for (size_t i = 0; i < SSV.size(); i++) { 8230b57cec5SDimitry Andric uint64_t AsanAlignment = 8; 8240b57cec5SDimitry Andric uint64_t NextField = i == SSV.size() - 1 ? TypeSize : SSV[i + 1].Offset; 8250b57cec5SDimitry Andric uint64_t PoisonSize = NextField - SSV[i].Offset - SSV[i].Size; 8260b57cec5SDimitry Andric uint64_t EndOffset = SSV[i].Offset + SSV[i].Size; 8270b57cec5SDimitry Andric if (PoisonSize < AsanAlignment || !SSV[i].Size || 8280b57cec5SDimitry Andric (NextField % AsanAlignment) != 0) 8290b57cec5SDimitry Andric continue; 8300b57cec5SDimitry Andric Builder.CreateCall( 8310b57cec5SDimitry Andric F, {Builder.CreateAdd(ThisPtr, Builder.getIntN(PtrSize, EndOffset)), 8320b57cec5SDimitry Andric Builder.getIntN(PtrSize, PoisonSize)}); 8330b57cec5SDimitry Andric } 8340b57cec5SDimitry Andric } 8350b57cec5SDimitry Andric 8360b57cec5SDimitry Andric /// EmitConstructorBody - Emits the body of the current constructor. 8370b57cec5SDimitry Andric void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) { 8380b57cec5SDimitry Andric EmitAsanPrologueOrEpilogue(true); 8390b57cec5SDimitry Andric const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl()); 8400b57cec5SDimitry Andric CXXCtorType CtorType = CurGD.getCtorType(); 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric assert((CGM.getTarget().getCXXABI().hasConstructorVariants() || 8430b57cec5SDimitry Andric CtorType == Ctor_Complete) && 8440b57cec5SDimitry Andric "can only generate complete ctor for this ABI"); 8450b57cec5SDimitry Andric 8460b57cec5SDimitry Andric // Before we go any further, try the complete->base constructor 8470b57cec5SDimitry Andric // delegation optimization. 8480b57cec5SDimitry Andric if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor) && 8490b57cec5SDimitry Andric CGM.getTarget().getCXXABI().hasConstructorVariants()) { 8500b57cec5SDimitry Andric EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args, Ctor->getEndLoc()); 8510b57cec5SDimitry Andric return; 8520b57cec5SDimitry Andric } 8530b57cec5SDimitry Andric 8540b57cec5SDimitry Andric const FunctionDecl *Definition = nullptr; 8550b57cec5SDimitry Andric Stmt *Body = Ctor->getBody(Definition); 8560b57cec5SDimitry Andric assert(Definition == Ctor && "emitting wrong constructor body"); 8570b57cec5SDimitry Andric 8580b57cec5SDimitry Andric // Enter the function-try-block before the constructor prologue if 8590b57cec5SDimitry Andric // applicable. 8600b57cec5SDimitry Andric bool IsTryBody = (Body && isa<CXXTryStmt>(Body)); 8610b57cec5SDimitry Andric if (IsTryBody) 8620b57cec5SDimitry Andric EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 8630b57cec5SDimitry Andric 8640b57cec5SDimitry Andric incrementProfileCounter(Body); 8650b57cec5SDimitry Andric 8660b57cec5SDimitry Andric RunCleanupsScope RunCleanups(*this); 8670b57cec5SDimitry Andric 8680b57cec5SDimitry Andric // TODO: in restricted cases, we can emit the vbase initializers of 8690b57cec5SDimitry Andric // a complete ctor and then delegate to the base ctor. 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andric // Emit the constructor prologue, i.e. the base and member 8720b57cec5SDimitry Andric // initializers. 8730b57cec5SDimitry Andric EmitCtorPrologue(Ctor, CtorType, Args); 8740b57cec5SDimitry Andric 8750b57cec5SDimitry Andric // Emit the body of the statement. 8760b57cec5SDimitry Andric if (IsTryBody) 8770b57cec5SDimitry Andric EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 8780b57cec5SDimitry Andric else if (Body) 8790b57cec5SDimitry Andric EmitStmt(Body); 8800b57cec5SDimitry Andric 8810b57cec5SDimitry Andric // Emit any cleanup blocks associated with the member or base 8820b57cec5SDimitry Andric // initializers, which includes (along the exceptional path) the 8830b57cec5SDimitry Andric // destructors for those members and bases that were fully 8840b57cec5SDimitry Andric // constructed. 8850b57cec5SDimitry Andric RunCleanups.ForceCleanup(); 8860b57cec5SDimitry Andric 8870b57cec5SDimitry Andric if (IsTryBody) 8880b57cec5SDimitry Andric ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 8890b57cec5SDimitry Andric } 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric namespace { 8920b57cec5SDimitry Andric /// RAII object to indicate that codegen is copying the value representation 8930b57cec5SDimitry Andric /// instead of the object representation. Useful when copying a struct or 8940b57cec5SDimitry Andric /// class which has uninitialized members and we're only performing 8950b57cec5SDimitry Andric /// lvalue-to-rvalue conversion on the object but not its members. 8960b57cec5SDimitry Andric class CopyingValueRepresentation { 8970b57cec5SDimitry Andric public: 8980b57cec5SDimitry Andric explicit CopyingValueRepresentation(CodeGenFunction &CGF) 8990b57cec5SDimitry Andric : CGF(CGF), OldSanOpts(CGF.SanOpts) { 9000b57cec5SDimitry Andric CGF.SanOpts.set(SanitizerKind::Bool, false); 9010b57cec5SDimitry Andric CGF.SanOpts.set(SanitizerKind::Enum, false); 9020b57cec5SDimitry Andric } 9030b57cec5SDimitry Andric ~CopyingValueRepresentation() { 9040b57cec5SDimitry Andric CGF.SanOpts = OldSanOpts; 9050b57cec5SDimitry Andric } 9060b57cec5SDimitry Andric private: 9070b57cec5SDimitry Andric CodeGenFunction &CGF; 9080b57cec5SDimitry Andric SanitizerSet OldSanOpts; 9090b57cec5SDimitry Andric }; 9100b57cec5SDimitry Andric } // end anonymous namespace 9110b57cec5SDimitry Andric 9120b57cec5SDimitry Andric namespace { 9130b57cec5SDimitry Andric class FieldMemcpyizer { 9140b57cec5SDimitry Andric public: 9150b57cec5SDimitry Andric FieldMemcpyizer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, 9160b57cec5SDimitry Andric const VarDecl *SrcRec) 9170b57cec5SDimitry Andric : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec), 9180b57cec5SDimitry Andric RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)), 9190b57cec5SDimitry Andric FirstField(nullptr), LastField(nullptr), FirstFieldOffset(0), 9200b57cec5SDimitry Andric LastFieldOffset(0), LastAddedFieldIndex(0) {} 9210b57cec5SDimitry Andric 9220b57cec5SDimitry Andric bool isMemcpyableField(FieldDecl *F) const { 9230b57cec5SDimitry Andric // Never memcpy fields when we are adding poisoned paddings. 9240b57cec5SDimitry Andric if (CGF.getContext().getLangOpts().SanitizeAddressFieldPadding) 9250b57cec5SDimitry Andric return false; 9260b57cec5SDimitry Andric Qualifiers Qual = F->getType().getQualifiers(); 9270b57cec5SDimitry Andric if (Qual.hasVolatile() || Qual.hasObjCLifetime()) 9280b57cec5SDimitry Andric return false; 9290b57cec5SDimitry Andric return true; 9300b57cec5SDimitry Andric } 9310b57cec5SDimitry Andric 9320b57cec5SDimitry Andric void addMemcpyableField(FieldDecl *F) { 933480093f4SDimitry Andric if (F->isZeroSize(CGF.getContext())) 934480093f4SDimitry Andric return; 9350b57cec5SDimitry Andric if (!FirstField) 9360b57cec5SDimitry Andric addInitialField(F); 9370b57cec5SDimitry Andric else 9380b57cec5SDimitry Andric addNextField(F); 9390b57cec5SDimitry Andric } 9400b57cec5SDimitry Andric 9410b57cec5SDimitry Andric CharUnits getMemcpySize(uint64_t FirstByteOffset) const { 9420b57cec5SDimitry Andric ASTContext &Ctx = CGF.getContext(); 9430b57cec5SDimitry Andric unsigned LastFieldSize = 9440b57cec5SDimitry Andric LastField->isBitField() 9450b57cec5SDimitry Andric ? LastField->getBitWidthValue(Ctx) 9460b57cec5SDimitry Andric : Ctx.toBits( 947e8d8bef9SDimitry Andric Ctx.getTypeInfoDataSizeInChars(LastField->getType()).Width); 9480b57cec5SDimitry Andric uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize - 9490b57cec5SDimitry Andric FirstByteOffset + Ctx.getCharWidth() - 1; 9500b57cec5SDimitry Andric CharUnits MemcpySize = Ctx.toCharUnitsFromBits(MemcpySizeBits); 9510b57cec5SDimitry Andric return MemcpySize; 9520b57cec5SDimitry Andric } 9530b57cec5SDimitry Andric 9540b57cec5SDimitry Andric void emitMemcpy() { 9550b57cec5SDimitry Andric // Give the subclass a chance to bail out if it feels the memcpy isn't 9560b57cec5SDimitry Andric // worth it (e.g. Hasn't aggregated enough data). 9570b57cec5SDimitry Andric if (!FirstField) { 9580b57cec5SDimitry Andric return; 9590b57cec5SDimitry Andric } 9600b57cec5SDimitry Andric 9610b57cec5SDimitry Andric uint64_t FirstByteOffset; 9620b57cec5SDimitry Andric if (FirstField->isBitField()) { 9630b57cec5SDimitry Andric const CGRecordLayout &RL = 9640b57cec5SDimitry Andric CGF.getTypes().getCGRecordLayout(FirstField->getParent()); 9650b57cec5SDimitry Andric const CGBitFieldInfo &BFInfo = RL.getBitFieldInfo(FirstField); 9660b57cec5SDimitry Andric // FirstFieldOffset is not appropriate for bitfields, 9670b57cec5SDimitry Andric // we need to use the storage offset instead. 9680b57cec5SDimitry Andric FirstByteOffset = CGF.getContext().toBits(BFInfo.StorageOffset); 9690b57cec5SDimitry Andric } else { 9700b57cec5SDimitry Andric FirstByteOffset = FirstFieldOffset; 9710b57cec5SDimitry Andric } 9720b57cec5SDimitry Andric 9730b57cec5SDimitry Andric CharUnits MemcpySize = getMemcpySize(FirstByteOffset); 9740b57cec5SDimitry Andric QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 9750b57cec5SDimitry Andric Address ThisPtr = CGF.LoadCXXThisAddress(); 9760b57cec5SDimitry Andric LValue DestLV = CGF.MakeAddrLValue(ThisPtr, RecordTy); 9770b57cec5SDimitry Andric LValue Dest = CGF.EmitLValueForFieldInitialization(DestLV, FirstField); 9780b57cec5SDimitry Andric llvm::Value *SrcPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(SrcRec)); 9790b57cec5SDimitry Andric LValue SrcLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); 9800b57cec5SDimitry Andric LValue Src = CGF.EmitLValueForFieldInitialization(SrcLV, FirstField); 9810b57cec5SDimitry Andric 982480093f4SDimitry Andric emitMemcpyIR( 983480093f4SDimitry Andric Dest.isBitField() ? Dest.getBitFieldAddress() : Dest.getAddress(CGF), 984480093f4SDimitry Andric Src.isBitField() ? Src.getBitFieldAddress() : Src.getAddress(CGF), 9850b57cec5SDimitry Andric MemcpySize); 9860b57cec5SDimitry Andric reset(); 9870b57cec5SDimitry Andric } 9880b57cec5SDimitry Andric 9890b57cec5SDimitry Andric void reset() { 9900b57cec5SDimitry Andric FirstField = nullptr; 9910b57cec5SDimitry Andric } 9920b57cec5SDimitry Andric 9930b57cec5SDimitry Andric protected: 9940b57cec5SDimitry Andric CodeGenFunction &CGF; 9950b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl; 9960b57cec5SDimitry Andric 9970b57cec5SDimitry Andric private: 9980b57cec5SDimitry Andric void emitMemcpyIR(Address DestPtr, Address SrcPtr, CharUnits Size) { 9990eae32dcSDimitry Andric DestPtr = CGF.Builder.CreateElementBitCast(DestPtr, CGF.Int8Ty); 10000eae32dcSDimitry Andric SrcPtr = CGF.Builder.CreateElementBitCast(SrcPtr, CGF.Int8Ty); 10010b57cec5SDimitry Andric CGF.Builder.CreateMemCpy(DestPtr, SrcPtr, Size.getQuantity()); 10020b57cec5SDimitry Andric } 10030b57cec5SDimitry Andric 10040b57cec5SDimitry Andric void addInitialField(FieldDecl *F) { 10050b57cec5SDimitry Andric FirstField = F; 10060b57cec5SDimitry Andric LastField = F; 10070b57cec5SDimitry Andric FirstFieldOffset = RecLayout.getFieldOffset(F->getFieldIndex()); 10080b57cec5SDimitry Andric LastFieldOffset = FirstFieldOffset; 10090b57cec5SDimitry Andric LastAddedFieldIndex = F->getFieldIndex(); 10100b57cec5SDimitry Andric } 10110b57cec5SDimitry Andric 10120b57cec5SDimitry Andric void addNextField(FieldDecl *F) { 10130b57cec5SDimitry Andric // For the most part, the following invariant will hold: 10140b57cec5SDimitry Andric // F->getFieldIndex() == LastAddedFieldIndex + 1 10150b57cec5SDimitry Andric // The one exception is that Sema won't add a copy-initializer for an 10160b57cec5SDimitry Andric // unnamed bitfield, which will show up here as a gap in the sequence. 10170b57cec5SDimitry Andric assert(F->getFieldIndex() >= LastAddedFieldIndex + 1 && 10180b57cec5SDimitry Andric "Cannot aggregate fields out of order."); 10190b57cec5SDimitry Andric LastAddedFieldIndex = F->getFieldIndex(); 10200b57cec5SDimitry Andric 10210b57cec5SDimitry Andric // The 'first' and 'last' fields are chosen by offset, rather than field 10220b57cec5SDimitry Andric // index. This allows the code to support bitfields, as well as regular 10230b57cec5SDimitry Andric // fields. 10240b57cec5SDimitry Andric uint64_t FOffset = RecLayout.getFieldOffset(F->getFieldIndex()); 10250b57cec5SDimitry Andric if (FOffset < FirstFieldOffset) { 10260b57cec5SDimitry Andric FirstField = F; 10270b57cec5SDimitry Andric FirstFieldOffset = FOffset; 10280b57cec5SDimitry Andric } else if (FOffset >= LastFieldOffset) { 10290b57cec5SDimitry Andric LastField = F; 10300b57cec5SDimitry Andric LastFieldOffset = FOffset; 10310b57cec5SDimitry Andric } 10320b57cec5SDimitry Andric } 10330b57cec5SDimitry Andric 10340b57cec5SDimitry Andric const VarDecl *SrcRec; 10350b57cec5SDimitry Andric const ASTRecordLayout &RecLayout; 10360b57cec5SDimitry Andric FieldDecl *FirstField; 10370b57cec5SDimitry Andric FieldDecl *LastField; 10380b57cec5SDimitry Andric uint64_t FirstFieldOffset, LastFieldOffset; 10390b57cec5SDimitry Andric unsigned LastAddedFieldIndex; 10400b57cec5SDimitry Andric }; 10410b57cec5SDimitry Andric 10420b57cec5SDimitry Andric class ConstructorMemcpyizer : public FieldMemcpyizer { 10430b57cec5SDimitry Andric private: 10440b57cec5SDimitry Andric /// Get source argument for copy constructor. Returns null if not a copy 10450b57cec5SDimitry Andric /// constructor. 10460b57cec5SDimitry Andric static const VarDecl *getTrivialCopySource(CodeGenFunction &CGF, 10470b57cec5SDimitry Andric const CXXConstructorDecl *CD, 10480b57cec5SDimitry Andric FunctionArgList &Args) { 10490b57cec5SDimitry Andric if (CD->isCopyOrMoveConstructor() && CD->isDefaulted()) 10500b57cec5SDimitry Andric return Args[CGF.CGM.getCXXABI().getSrcArgforCopyCtor(CD, Args)]; 10510b57cec5SDimitry Andric return nullptr; 10520b57cec5SDimitry Andric } 10530b57cec5SDimitry Andric 10540b57cec5SDimitry Andric // Returns true if a CXXCtorInitializer represents a member initialization 10550b57cec5SDimitry Andric // that can be rolled into a memcpy. 10560b57cec5SDimitry Andric bool isMemberInitMemcpyable(CXXCtorInitializer *MemberInit) const { 10570b57cec5SDimitry Andric if (!MemcpyableCtor) 10580b57cec5SDimitry Andric return false; 10590b57cec5SDimitry Andric FieldDecl *Field = MemberInit->getMember(); 10600b57cec5SDimitry Andric assert(Field && "No field for member init."); 10610b57cec5SDimitry Andric QualType FieldType = Field->getType(); 10620b57cec5SDimitry Andric CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); 10630b57cec5SDimitry Andric 10640b57cec5SDimitry Andric // Bail out on non-memcpyable, not-trivially-copyable members. 10650b57cec5SDimitry Andric if (!(CE && isMemcpyEquivalentSpecialMember(CE->getConstructor())) && 10660b57cec5SDimitry Andric !(FieldType.isTriviallyCopyableType(CGF.getContext()) || 10670b57cec5SDimitry Andric FieldType->isReferenceType())) 10680b57cec5SDimitry Andric return false; 10690b57cec5SDimitry Andric 10700b57cec5SDimitry Andric // Bail out on volatile fields. 10710b57cec5SDimitry Andric if (!isMemcpyableField(Field)) 10720b57cec5SDimitry Andric return false; 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andric // Otherwise we're good. 10750b57cec5SDimitry Andric return true; 10760b57cec5SDimitry Andric } 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric public: 10790b57cec5SDimitry Andric ConstructorMemcpyizer(CodeGenFunction &CGF, const CXXConstructorDecl *CD, 10800b57cec5SDimitry Andric FunctionArgList &Args) 10810b57cec5SDimitry Andric : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CGF, CD, Args)), 10820b57cec5SDimitry Andric ConstructorDecl(CD), 10830b57cec5SDimitry Andric MemcpyableCtor(CD->isDefaulted() && 10840b57cec5SDimitry Andric CD->isCopyOrMoveConstructor() && 10850b57cec5SDimitry Andric CGF.getLangOpts().getGC() == LangOptions::NonGC), 10860b57cec5SDimitry Andric Args(Args) { } 10870b57cec5SDimitry Andric 10880b57cec5SDimitry Andric void addMemberInitializer(CXXCtorInitializer *MemberInit) { 10890b57cec5SDimitry Andric if (isMemberInitMemcpyable(MemberInit)) { 10900b57cec5SDimitry Andric AggregatedInits.push_back(MemberInit); 10910b57cec5SDimitry Andric addMemcpyableField(MemberInit->getMember()); 10920b57cec5SDimitry Andric } else { 10930b57cec5SDimitry Andric emitAggregatedInits(); 10940b57cec5SDimitry Andric EmitMemberInitializer(CGF, ConstructorDecl->getParent(), MemberInit, 10950b57cec5SDimitry Andric ConstructorDecl, Args); 10960b57cec5SDimitry Andric } 10970b57cec5SDimitry Andric } 10980b57cec5SDimitry Andric 10990b57cec5SDimitry Andric void emitAggregatedInits() { 11000b57cec5SDimitry Andric if (AggregatedInits.size() <= 1) { 11010b57cec5SDimitry Andric // This memcpy is too small to be worthwhile. Fall back on default 11020b57cec5SDimitry Andric // codegen. 11030b57cec5SDimitry Andric if (!AggregatedInits.empty()) { 11040b57cec5SDimitry Andric CopyingValueRepresentation CVR(CGF); 11050b57cec5SDimitry Andric EmitMemberInitializer(CGF, ConstructorDecl->getParent(), 11060b57cec5SDimitry Andric AggregatedInits[0], ConstructorDecl, Args); 11070b57cec5SDimitry Andric AggregatedInits.clear(); 11080b57cec5SDimitry Andric } 11090b57cec5SDimitry Andric reset(); 11100b57cec5SDimitry Andric return; 11110b57cec5SDimitry Andric } 11120b57cec5SDimitry Andric 11130b57cec5SDimitry Andric pushEHDestructors(); 11140b57cec5SDimitry Andric emitMemcpy(); 11150b57cec5SDimitry Andric AggregatedInits.clear(); 11160b57cec5SDimitry Andric } 11170b57cec5SDimitry Andric 11180b57cec5SDimitry Andric void pushEHDestructors() { 11190b57cec5SDimitry Andric Address ThisPtr = CGF.LoadCXXThisAddress(); 11200b57cec5SDimitry Andric QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 11210b57cec5SDimitry Andric LValue LHS = CGF.MakeAddrLValue(ThisPtr, RecordTy); 11220b57cec5SDimitry Andric 11230b57cec5SDimitry Andric for (unsigned i = 0; i < AggregatedInits.size(); ++i) { 11240b57cec5SDimitry Andric CXXCtorInitializer *MemberInit = AggregatedInits[i]; 11250b57cec5SDimitry Andric QualType FieldType = MemberInit->getAnyMember()->getType(); 11260b57cec5SDimitry Andric QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 11270b57cec5SDimitry Andric if (!CGF.needsEHCleanup(dtorKind)) 11280b57cec5SDimitry Andric continue; 11290b57cec5SDimitry Andric LValue FieldLHS = LHS; 11300b57cec5SDimitry Andric EmitLValueForAnyFieldInitialization(CGF, MemberInit, FieldLHS); 1131480093f4SDimitry Andric CGF.pushEHDestroy(dtorKind, FieldLHS.getAddress(CGF), FieldType); 11320b57cec5SDimitry Andric } 11330b57cec5SDimitry Andric } 11340b57cec5SDimitry Andric 11350b57cec5SDimitry Andric void finish() { 11360b57cec5SDimitry Andric emitAggregatedInits(); 11370b57cec5SDimitry Andric } 11380b57cec5SDimitry Andric 11390b57cec5SDimitry Andric private: 11400b57cec5SDimitry Andric const CXXConstructorDecl *ConstructorDecl; 11410b57cec5SDimitry Andric bool MemcpyableCtor; 11420b57cec5SDimitry Andric FunctionArgList &Args; 11430b57cec5SDimitry Andric SmallVector<CXXCtorInitializer*, 16> AggregatedInits; 11440b57cec5SDimitry Andric }; 11450b57cec5SDimitry Andric 11460b57cec5SDimitry Andric class AssignmentMemcpyizer : public FieldMemcpyizer { 11470b57cec5SDimitry Andric private: 11480b57cec5SDimitry Andric // Returns the memcpyable field copied by the given statement, if one 11490b57cec5SDimitry Andric // exists. Otherwise returns null. 11500b57cec5SDimitry Andric FieldDecl *getMemcpyableField(Stmt *S) { 11510b57cec5SDimitry Andric if (!AssignmentsMemcpyable) 11520b57cec5SDimitry Andric return nullptr; 11530b57cec5SDimitry Andric if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) { 11540b57cec5SDimitry Andric // Recognise trivial assignments. 11550b57cec5SDimitry Andric if (BO->getOpcode() != BO_Assign) 11560b57cec5SDimitry Andric return nullptr; 11570b57cec5SDimitry Andric MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS()); 11580b57cec5SDimitry Andric if (!ME) 11590b57cec5SDimitry Andric return nullptr; 11600b57cec5SDimitry Andric FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl()); 11610b57cec5SDimitry Andric if (!Field || !isMemcpyableField(Field)) 11620b57cec5SDimitry Andric return nullptr; 11630b57cec5SDimitry Andric Stmt *RHS = BO->getRHS(); 11640b57cec5SDimitry Andric if (ImplicitCastExpr *EC = dyn_cast<ImplicitCastExpr>(RHS)) 11650b57cec5SDimitry Andric RHS = EC->getSubExpr(); 11660b57cec5SDimitry Andric if (!RHS) 11670b57cec5SDimitry Andric return nullptr; 11680b57cec5SDimitry Andric if (MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) { 11690b57cec5SDimitry Andric if (ME2->getMemberDecl() == Field) 11700b57cec5SDimitry Andric return Field; 11710b57cec5SDimitry Andric } 11720b57cec5SDimitry Andric return nullptr; 11730b57cec5SDimitry Andric } else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) { 11740b57cec5SDimitry Andric CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl()); 11750b57cec5SDimitry Andric if (!(MD && isMemcpyEquivalentSpecialMember(MD))) 11760b57cec5SDimitry Andric return nullptr; 11770b57cec5SDimitry Andric MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument()); 11780b57cec5SDimitry Andric if (!IOA) 11790b57cec5SDimitry Andric return nullptr; 11800b57cec5SDimitry Andric FieldDecl *Field = dyn_cast<FieldDecl>(IOA->getMemberDecl()); 11810b57cec5SDimitry Andric if (!Field || !isMemcpyableField(Field)) 11820b57cec5SDimitry Andric return nullptr; 11830b57cec5SDimitry Andric MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0)); 11840b57cec5SDimitry Andric if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->getMemberDecl())) 11850b57cec5SDimitry Andric return nullptr; 11860b57cec5SDimitry Andric return Field; 11870b57cec5SDimitry Andric } else if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 11880b57cec5SDimitry Andric FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl()); 11890b57cec5SDimitry Andric if (!FD || FD->getBuiltinID() != Builtin::BI__builtin_memcpy) 11900b57cec5SDimitry Andric return nullptr; 11910b57cec5SDimitry Andric Expr *DstPtr = CE->getArg(0); 11920b57cec5SDimitry Andric if (ImplicitCastExpr *DC = dyn_cast<ImplicitCastExpr>(DstPtr)) 11930b57cec5SDimitry Andric DstPtr = DC->getSubExpr(); 11940b57cec5SDimitry Andric UnaryOperator *DUO = dyn_cast<UnaryOperator>(DstPtr); 11950b57cec5SDimitry Andric if (!DUO || DUO->getOpcode() != UO_AddrOf) 11960b57cec5SDimitry Andric return nullptr; 11970b57cec5SDimitry Andric MemberExpr *ME = dyn_cast<MemberExpr>(DUO->getSubExpr()); 11980b57cec5SDimitry Andric if (!ME) 11990b57cec5SDimitry Andric return nullptr; 12000b57cec5SDimitry Andric FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl()); 12010b57cec5SDimitry Andric if (!Field || !isMemcpyableField(Field)) 12020b57cec5SDimitry Andric return nullptr; 12030b57cec5SDimitry Andric Expr *SrcPtr = CE->getArg(1); 12040b57cec5SDimitry Andric if (ImplicitCastExpr *SC = dyn_cast<ImplicitCastExpr>(SrcPtr)) 12050b57cec5SDimitry Andric SrcPtr = SC->getSubExpr(); 12060b57cec5SDimitry Andric UnaryOperator *SUO = dyn_cast<UnaryOperator>(SrcPtr); 12070b57cec5SDimitry Andric if (!SUO || SUO->getOpcode() != UO_AddrOf) 12080b57cec5SDimitry Andric return nullptr; 12090b57cec5SDimitry Andric MemberExpr *ME2 = dyn_cast<MemberExpr>(SUO->getSubExpr()); 12100b57cec5SDimitry Andric if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->getMemberDecl())) 12110b57cec5SDimitry Andric return nullptr; 12120b57cec5SDimitry Andric return Field; 12130b57cec5SDimitry Andric } 12140b57cec5SDimitry Andric 12150b57cec5SDimitry Andric return nullptr; 12160b57cec5SDimitry Andric } 12170b57cec5SDimitry Andric 12180b57cec5SDimitry Andric bool AssignmentsMemcpyable; 12190b57cec5SDimitry Andric SmallVector<Stmt*, 16> AggregatedStmts; 12200b57cec5SDimitry Andric 12210b57cec5SDimitry Andric public: 12220b57cec5SDimitry Andric AssignmentMemcpyizer(CodeGenFunction &CGF, const CXXMethodDecl *AD, 12230b57cec5SDimitry Andric FunctionArgList &Args) 12240b57cec5SDimitry Andric : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]), 12250b57cec5SDimitry Andric AssignmentsMemcpyable(CGF.getLangOpts().getGC() == LangOptions::NonGC) { 12260b57cec5SDimitry Andric assert(Args.size() == 2); 12270b57cec5SDimitry Andric } 12280b57cec5SDimitry Andric 12290b57cec5SDimitry Andric void emitAssignment(Stmt *S) { 12300b57cec5SDimitry Andric FieldDecl *F = getMemcpyableField(S); 12310b57cec5SDimitry Andric if (F) { 12320b57cec5SDimitry Andric addMemcpyableField(F); 12330b57cec5SDimitry Andric AggregatedStmts.push_back(S); 12340b57cec5SDimitry Andric } else { 12350b57cec5SDimitry Andric emitAggregatedStmts(); 12360b57cec5SDimitry Andric CGF.EmitStmt(S); 12370b57cec5SDimitry Andric } 12380b57cec5SDimitry Andric } 12390b57cec5SDimitry Andric 12400b57cec5SDimitry Andric void emitAggregatedStmts() { 12410b57cec5SDimitry Andric if (AggregatedStmts.size() <= 1) { 12420b57cec5SDimitry Andric if (!AggregatedStmts.empty()) { 12430b57cec5SDimitry Andric CopyingValueRepresentation CVR(CGF); 12440b57cec5SDimitry Andric CGF.EmitStmt(AggregatedStmts[0]); 12450b57cec5SDimitry Andric } 12460b57cec5SDimitry Andric reset(); 12470b57cec5SDimitry Andric } 12480b57cec5SDimitry Andric 12490b57cec5SDimitry Andric emitMemcpy(); 12500b57cec5SDimitry Andric AggregatedStmts.clear(); 12510b57cec5SDimitry Andric } 12520b57cec5SDimitry Andric 12530b57cec5SDimitry Andric void finish() { 12540b57cec5SDimitry Andric emitAggregatedStmts(); 12550b57cec5SDimitry Andric } 12560b57cec5SDimitry Andric }; 12570b57cec5SDimitry Andric } // end anonymous namespace 12580b57cec5SDimitry Andric 12590b57cec5SDimitry Andric static bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit) { 12600b57cec5SDimitry Andric const Type *BaseType = BaseInit->getBaseClass(); 12610b57cec5SDimitry Andric const auto *BaseClassDecl = 1262a7dea167SDimitry Andric cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl()); 12630b57cec5SDimitry Andric return BaseClassDecl->isDynamicClass(); 12640b57cec5SDimitry Andric } 12650b57cec5SDimitry Andric 12660b57cec5SDimitry Andric /// EmitCtorPrologue - This routine generates necessary code to initialize 12670b57cec5SDimitry Andric /// base classes and non-static data members belonging to this constructor. 12680b57cec5SDimitry Andric void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, 12690b57cec5SDimitry Andric CXXCtorType CtorType, 12700b57cec5SDimitry Andric FunctionArgList &Args) { 12710b57cec5SDimitry Andric if (CD->isDelegatingConstructor()) 12720b57cec5SDimitry Andric return EmitDelegatingCXXConstructorCall(CD, Args); 12730b57cec5SDimitry Andric 12740b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = CD->getParent(); 12750b57cec5SDimitry Andric 12760b57cec5SDimitry Andric CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 12770b57cec5SDimitry Andric E = CD->init_end(); 12780b57cec5SDimitry Andric 12790b57cec5SDimitry Andric // Virtual base initializers first, if any. They aren't needed if: 12800b57cec5SDimitry Andric // - This is a base ctor variant 12810b57cec5SDimitry Andric // - There are no vbases 12820b57cec5SDimitry Andric // - The class is abstract, so a complete object of it cannot be constructed 12830b57cec5SDimitry Andric // 12840b57cec5SDimitry Andric // The check for an abstract class is necessary because sema may not have 12850b57cec5SDimitry Andric // marked virtual base destructors referenced. 12860b57cec5SDimitry Andric bool ConstructVBases = CtorType != Ctor_Base && 12870b57cec5SDimitry Andric ClassDecl->getNumVBases() != 0 && 12880b57cec5SDimitry Andric !ClassDecl->isAbstract(); 12890b57cec5SDimitry Andric 12900b57cec5SDimitry Andric // In the Microsoft C++ ABI, there are no constructor variants. Instead, the 12910b57cec5SDimitry Andric // constructor of a class with virtual bases takes an additional parameter to 12920b57cec5SDimitry Andric // conditionally construct the virtual bases. Emit that check here. 12930b57cec5SDimitry Andric llvm::BasicBlock *BaseCtorContinueBB = nullptr; 12940b57cec5SDimitry Andric if (ConstructVBases && 12950b57cec5SDimitry Andric !CGM.getTarget().getCXXABI().hasConstructorVariants()) { 12960b57cec5SDimitry Andric BaseCtorContinueBB = 12970b57cec5SDimitry Andric CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this, ClassDecl); 12980b57cec5SDimitry Andric assert(BaseCtorContinueBB); 12990b57cec5SDimitry Andric } 13000b57cec5SDimitry Andric 13010b57cec5SDimitry Andric llvm::Value *const OldThis = CXXThisValue; 13020b57cec5SDimitry Andric for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) { 13030b57cec5SDimitry Andric if (!ConstructVBases) 13040b57cec5SDimitry Andric continue; 13050b57cec5SDimitry Andric if (CGM.getCodeGenOpts().StrictVTablePointers && 13060b57cec5SDimitry Andric CGM.getCodeGenOpts().OptimizationLevel > 0 && 13070b57cec5SDimitry Andric isInitializerOfDynamicClass(*B)) 13080b57cec5SDimitry Andric CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); 13090b57cec5SDimitry Andric EmitBaseInitializer(*this, ClassDecl, *B); 13100b57cec5SDimitry Andric } 13110b57cec5SDimitry Andric 13120b57cec5SDimitry Andric if (BaseCtorContinueBB) { 13130b57cec5SDimitry Andric // Complete object handler should continue to the remaining initializers. 13140b57cec5SDimitry Andric Builder.CreateBr(BaseCtorContinueBB); 13150b57cec5SDimitry Andric EmitBlock(BaseCtorContinueBB); 13160b57cec5SDimitry Andric } 13170b57cec5SDimitry Andric 13180b57cec5SDimitry Andric // Then, non-virtual base initializers. 13190b57cec5SDimitry Andric for (; B != E && (*B)->isBaseInitializer(); B++) { 13200b57cec5SDimitry Andric assert(!(*B)->isBaseVirtual()); 13210b57cec5SDimitry Andric 13220b57cec5SDimitry Andric if (CGM.getCodeGenOpts().StrictVTablePointers && 13230b57cec5SDimitry Andric CGM.getCodeGenOpts().OptimizationLevel > 0 && 13240b57cec5SDimitry Andric isInitializerOfDynamicClass(*B)) 13250b57cec5SDimitry Andric CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); 13260b57cec5SDimitry Andric EmitBaseInitializer(*this, ClassDecl, *B); 13270b57cec5SDimitry Andric } 13280b57cec5SDimitry Andric 13290b57cec5SDimitry Andric CXXThisValue = OldThis; 13300b57cec5SDimitry Andric 13310b57cec5SDimitry Andric InitializeVTablePointers(ClassDecl); 13320b57cec5SDimitry Andric 13330b57cec5SDimitry Andric // And finally, initialize class members. 13340b57cec5SDimitry Andric FieldConstructionScope FCS(*this, LoadCXXThisAddress()); 13350b57cec5SDimitry Andric ConstructorMemcpyizer CM(*this, CD, Args); 13360b57cec5SDimitry Andric for (; B != E; B++) { 13370b57cec5SDimitry Andric CXXCtorInitializer *Member = (*B); 13380b57cec5SDimitry Andric assert(!Member->isBaseInitializer()); 13390b57cec5SDimitry Andric assert(Member->isAnyMemberInitializer() && 13400b57cec5SDimitry Andric "Delegating initializer on non-delegating constructor"); 13410b57cec5SDimitry Andric CM.addMemberInitializer(Member); 13420b57cec5SDimitry Andric } 13430b57cec5SDimitry Andric CM.finish(); 13440b57cec5SDimitry Andric } 13450b57cec5SDimitry Andric 13460b57cec5SDimitry Andric static bool 13470b57cec5SDimitry Andric FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field); 13480b57cec5SDimitry Andric 13490b57cec5SDimitry Andric static bool 13500b57cec5SDimitry Andric HasTrivialDestructorBody(ASTContext &Context, 13510b57cec5SDimitry Andric const CXXRecordDecl *BaseClassDecl, 13520b57cec5SDimitry Andric const CXXRecordDecl *MostDerivedClassDecl) 13530b57cec5SDimitry Andric { 13540b57cec5SDimitry Andric // If the destructor is trivial we don't have to check anything else. 13550b57cec5SDimitry Andric if (BaseClassDecl->hasTrivialDestructor()) 13560b57cec5SDimitry Andric return true; 13570b57cec5SDimitry Andric 13580b57cec5SDimitry Andric if (!BaseClassDecl->getDestructor()->hasTrivialBody()) 13590b57cec5SDimitry Andric return false; 13600b57cec5SDimitry Andric 13610b57cec5SDimitry Andric // Check fields. 13620b57cec5SDimitry Andric for (const auto *Field : BaseClassDecl->fields()) 13630b57cec5SDimitry Andric if (!FieldHasTrivialDestructorBody(Context, Field)) 13640b57cec5SDimitry Andric return false; 13650b57cec5SDimitry Andric 13660b57cec5SDimitry Andric // Check non-virtual bases. 13670b57cec5SDimitry Andric for (const auto &I : BaseClassDecl->bases()) { 13680b57cec5SDimitry Andric if (I.isVirtual()) 13690b57cec5SDimitry Andric continue; 13700b57cec5SDimitry Andric 13710b57cec5SDimitry Andric const CXXRecordDecl *NonVirtualBase = 13720b57cec5SDimitry Andric cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 13730b57cec5SDimitry Andric if (!HasTrivialDestructorBody(Context, NonVirtualBase, 13740b57cec5SDimitry Andric MostDerivedClassDecl)) 13750b57cec5SDimitry Andric return false; 13760b57cec5SDimitry Andric } 13770b57cec5SDimitry Andric 13780b57cec5SDimitry Andric if (BaseClassDecl == MostDerivedClassDecl) { 13790b57cec5SDimitry Andric // Check virtual bases. 13800b57cec5SDimitry Andric for (const auto &I : BaseClassDecl->vbases()) { 13810b57cec5SDimitry Andric const CXXRecordDecl *VirtualBase = 13820b57cec5SDimitry Andric cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 13830b57cec5SDimitry Andric if (!HasTrivialDestructorBody(Context, VirtualBase, 13840b57cec5SDimitry Andric MostDerivedClassDecl)) 13850b57cec5SDimitry Andric return false; 13860b57cec5SDimitry Andric } 13870b57cec5SDimitry Andric } 13880b57cec5SDimitry Andric 13890b57cec5SDimitry Andric return true; 13900b57cec5SDimitry Andric } 13910b57cec5SDimitry Andric 13920b57cec5SDimitry Andric static bool 13930b57cec5SDimitry Andric FieldHasTrivialDestructorBody(ASTContext &Context, 13940b57cec5SDimitry Andric const FieldDecl *Field) 13950b57cec5SDimitry Andric { 13960b57cec5SDimitry Andric QualType FieldBaseElementType = Context.getBaseElementType(Field->getType()); 13970b57cec5SDimitry Andric 13980b57cec5SDimitry Andric const RecordType *RT = FieldBaseElementType->getAs<RecordType>(); 13990b57cec5SDimitry Andric if (!RT) 14000b57cec5SDimitry Andric return true; 14010b57cec5SDimitry Andric 14020b57cec5SDimitry Andric CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 14030b57cec5SDimitry Andric 14040b57cec5SDimitry Andric // The destructor for an implicit anonymous union member is never invoked. 14050b57cec5SDimitry Andric if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion()) 14060b57cec5SDimitry Andric return false; 14070b57cec5SDimitry Andric 14080b57cec5SDimitry Andric return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl); 14090b57cec5SDimitry Andric } 14100b57cec5SDimitry Andric 14110b57cec5SDimitry Andric /// CanSkipVTablePointerInitialization - Check whether we need to initialize 14120b57cec5SDimitry Andric /// any vtable pointers before calling this destructor. 14130b57cec5SDimitry Andric static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF, 14140b57cec5SDimitry Andric const CXXDestructorDecl *Dtor) { 14150b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = Dtor->getParent(); 14160b57cec5SDimitry Andric if (!ClassDecl->isDynamicClass()) 14170b57cec5SDimitry Andric return true; 14180b57cec5SDimitry Andric 1419349cc55cSDimitry Andric // For a final class, the vtable pointer is known to already point to the 1420349cc55cSDimitry Andric // class's vtable. 1421349cc55cSDimitry Andric if (ClassDecl->isEffectivelyFinal()) 1422349cc55cSDimitry Andric return true; 1423349cc55cSDimitry Andric 14240b57cec5SDimitry Andric if (!Dtor->hasTrivialBody()) 14250b57cec5SDimitry Andric return false; 14260b57cec5SDimitry Andric 14270b57cec5SDimitry Andric // Check the fields. 14280b57cec5SDimitry Andric for (const auto *Field : ClassDecl->fields()) 14290b57cec5SDimitry Andric if (!FieldHasTrivialDestructorBody(CGF.getContext(), Field)) 14300b57cec5SDimitry Andric return false; 14310b57cec5SDimitry Andric 14320b57cec5SDimitry Andric return true; 14330b57cec5SDimitry Andric } 14340b57cec5SDimitry Andric 14350b57cec5SDimitry Andric /// EmitDestructorBody - Emits the body of the current destructor. 14360b57cec5SDimitry Andric void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { 14370b57cec5SDimitry Andric const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl()); 14380b57cec5SDimitry Andric CXXDtorType DtorType = CurGD.getDtorType(); 14390b57cec5SDimitry Andric 14400b57cec5SDimitry Andric // For an abstract class, non-base destructors are never used (and can't 14410b57cec5SDimitry Andric // be emitted in general, because vbase dtors may not have been validated 14420b57cec5SDimitry Andric // by Sema), but the Itanium ABI doesn't make them optional and Clang may 14430b57cec5SDimitry Andric // in fact emit references to them from other compilations, so emit them 14440b57cec5SDimitry Andric // as functions containing a trap instruction. 14450b57cec5SDimitry Andric if (DtorType != Dtor_Base && Dtor->getParent()->isAbstract()) { 14460b57cec5SDimitry Andric llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); 14470b57cec5SDimitry Andric TrapCall->setDoesNotReturn(); 14480b57cec5SDimitry Andric TrapCall->setDoesNotThrow(); 14490b57cec5SDimitry Andric Builder.CreateUnreachable(); 14500b57cec5SDimitry Andric Builder.ClearInsertionPoint(); 14510b57cec5SDimitry Andric return; 14520b57cec5SDimitry Andric } 14530b57cec5SDimitry Andric 14540b57cec5SDimitry Andric Stmt *Body = Dtor->getBody(); 14550b57cec5SDimitry Andric if (Body) 14560b57cec5SDimitry Andric incrementProfileCounter(Body); 14570b57cec5SDimitry Andric 14580b57cec5SDimitry Andric // The call to operator delete in a deleting destructor happens 14590b57cec5SDimitry Andric // outside of the function-try-block, which means it's always 14600b57cec5SDimitry Andric // possible to delegate the destructor body to the complete 14610b57cec5SDimitry Andric // destructor. Do so. 14620b57cec5SDimitry Andric if (DtorType == Dtor_Deleting) { 14630b57cec5SDimitry Andric RunCleanupsScope DtorEpilogue(*this); 14640b57cec5SDimitry Andric EnterDtorCleanups(Dtor, Dtor_Deleting); 14650b57cec5SDimitry Andric if (HaveInsertPoint()) { 14660b57cec5SDimitry Andric QualType ThisTy = Dtor->getThisObjectType(); 14670b57cec5SDimitry Andric EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, 14680b57cec5SDimitry Andric /*Delegating=*/false, LoadCXXThisAddress(), ThisTy); 14690b57cec5SDimitry Andric } 14700b57cec5SDimitry Andric return; 14710b57cec5SDimitry Andric } 14720b57cec5SDimitry Andric 14730b57cec5SDimitry Andric // If the body is a function-try-block, enter the try before 14740b57cec5SDimitry Andric // anything else. 14750b57cec5SDimitry Andric bool isTryBody = (Body && isa<CXXTryStmt>(Body)); 14760b57cec5SDimitry Andric if (isTryBody) 14770b57cec5SDimitry Andric EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 14780b57cec5SDimitry Andric EmitAsanPrologueOrEpilogue(false); 14790b57cec5SDimitry Andric 14800b57cec5SDimitry Andric // Enter the epilogue cleanups. 14810b57cec5SDimitry Andric RunCleanupsScope DtorEpilogue(*this); 14820b57cec5SDimitry Andric 14830b57cec5SDimitry Andric // If this is the complete variant, just invoke the base variant; 14840b57cec5SDimitry Andric // the epilogue will destruct the virtual bases. But we can't do 14850b57cec5SDimitry Andric // this optimization if the body is a function-try-block, because 14860b57cec5SDimitry Andric // we'd introduce *two* handler blocks. In the Microsoft ABI, we 14870b57cec5SDimitry Andric // always delegate because we might not have a definition in this TU. 14880b57cec5SDimitry Andric switch (DtorType) { 14890b57cec5SDimitry Andric case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT"); 14900b57cec5SDimitry Andric case Dtor_Deleting: llvm_unreachable("already handled deleting case"); 14910b57cec5SDimitry Andric 14920b57cec5SDimitry Andric case Dtor_Complete: 14930b57cec5SDimitry Andric assert((Body || getTarget().getCXXABI().isMicrosoft()) && 14940b57cec5SDimitry Andric "can't emit a dtor without a body for non-Microsoft ABIs"); 14950b57cec5SDimitry Andric 14960b57cec5SDimitry Andric // Enter the cleanup scopes for virtual bases. 14970b57cec5SDimitry Andric EnterDtorCleanups(Dtor, Dtor_Complete); 14980b57cec5SDimitry Andric 14990b57cec5SDimitry Andric if (!isTryBody) { 15000b57cec5SDimitry Andric QualType ThisTy = Dtor->getThisObjectType(); 15010b57cec5SDimitry Andric EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false, 15020b57cec5SDimitry Andric /*Delegating=*/false, LoadCXXThisAddress(), ThisTy); 15030b57cec5SDimitry Andric break; 15040b57cec5SDimitry Andric } 15050b57cec5SDimitry Andric 15060b57cec5SDimitry Andric // Fallthrough: act like we're in the base variant. 15070b57cec5SDimitry Andric LLVM_FALLTHROUGH; 15080b57cec5SDimitry Andric 15090b57cec5SDimitry Andric case Dtor_Base: 15100b57cec5SDimitry Andric assert(Body); 15110b57cec5SDimitry Andric 15120b57cec5SDimitry Andric // Enter the cleanup scopes for fields and non-virtual bases. 15130b57cec5SDimitry Andric EnterDtorCleanups(Dtor, Dtor_Base); 15140b57cec5SDimitry Andric 15150b57cec5SDimitry Andric // Initialize the vtable pointers before entering the body. 15160b57cec5SDimitry Andric if (!CanSkipVTablePointerInitialization(*this, Dtor)) { 15170b57cec5SDimitry Andric // Insert the llvm.launder.invariant.group intrinsic before initializing 15180b57cec5SDimitry Andric // the vptrs to cancel any previous assumptions we might have made. 15190b57cec5SDimitry Andric if (CGM.getCodeGenOpts().StrictVTablePointers && 15200b57cec5SDimitry Andric CGM.getCodeGenOpts().OptimizationLevel > 0) 15210b57cec5SDimitry Andric CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); 15220b57cec5SDimitry Andric InitializeVTablePointers(Dtor->getParent()); 15230b57cec5SDimitry Andric } 15240b57cec5SDimitry Andric 15250b57cec5SDimitry Andric if (isTryBody) 15260b57cec5SDimitry Andric EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 15270b57cec5SDimitry Andric else if (Body) 15280b57cec5SDimitry Andric EmitStmt(Body); 15290b57cec5SDimitry Andric else { 15300b57cec5SDimitry Andric assert(Dtor->isImplicit() && "bodyless dtor not implicit"); 15310b57cec5SDimitry Andric // nothing to do besides what's in the epilogue 15320b57cec5SDimitry Andric } 15330b57cec5SDimitry Andric // -fapple-kext must inline any call to this dtor into 15340b57cec5SDimitry Andric // the caller's body. 15350b57cec5SDimitry Andric if (getLangOpts().AppleKext) 15360b57cec5SDimitry Andric CurFn->addFnAttr(llvm::Attribute::AlwaysInline); 15370b57cec5SDimitry Andric 15380b57cec5SDimitry Andric break; 15390b57cec5SDimitry Andric } 15400b57cec5SDimitry Andric 15410b57cec5SDimitry Andric // Jump out through the epilogue cleanups. 15420b57cec5SDimitry Andric DtorEpilogue.ForceCleanup(); 15430b57cec5SDimitry Andric 15440b57cec5SDimitry Andric // Exit the try if applicable. 15450b57cec5SDimitry Andric if (isTryBody) 15460b57cec5SDimitry Andric ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 15470b57cec5SDimitry Andric } 15480b57cec5SDimitry Andric 15490b57cec5SDimitry Andric void CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args) { 15500b57cec5SDimitry Andric const CXXMethodDecl *AssignOp = cast<CXXMethodDecl>(CurGD.getDecl()); 15510b57cec5SDimitry Andric const Stmt *RootS = AssignOp->getBody(); 15520b57cec5SDimitry Andric assert(isa<CompoundStmt>(RootS) && 15530b57cec5SDimitry Andric "Body of an implicit assignment operator should be compound stmt."); 15540b57cec5SDimitry Andric const CompoundStmt *RootCS = cast<CompoundStmt>(RootS); 15550b57cec5SDimitry Andric 15560b57cec5SDimitry Andric LexicalScope Scope(*this, RootCS->getSourceRange()); 15570b57cec5SDimitry Andric 15580b57cec5SDimitry Andric incrementProfileCounter(RootCS); 15590b57cec5SDimitry Andric AssignmentMemcpyizer AM(*this, AssignOp, Args); 15600b57cec5SDimitry Andric for (auto *I : RootCS->body()) 15610b57cec5SDimitry Andric AM.emitAssignment(I); 15620b57cec5SDimitry Andric AM.finish(); 15630b57cec5SDimitry Andric } 15640b57cec5SDimitry Andric 15650b57cec5SDimitry Andric namespace { 15660b57cec5SDimitry Andric llvm::Value *LoadThisForDtorDelete(CodeGenFunction &CGF, 15670b57cec5SDimitry Andric const CXXDestructorDecl *DD) { 15680b57cec5SDimitry Andric if (Expr *ThisArg = DD->getOperatorDeleteThisArg()) 15690b57cec5SDimitry Andric return CGF.EmitScalarExpr(ThisArg); 15700b57cec5SDimitry Andric return CGF.LoadCXXThis(); 15710b57cec5SDimitry Andric } 15720b57cec5SDimitry Andric 15730b57cec5SDimitry Andric /// Call the operator delete associated with the current destructor. 15740b57cec5SDimitry Andric struct CallDtorDelete final : EHScopeStack::Cleanup { 15750b57cec5SDimitry Andric CallDtorDelete() {} 15760b57cec5SDimitry Andric 15770b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 15780b57cec5SDimitry Andric const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 15790b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = Dtor->getParent(); 15800b57cec5SDimitry Andric CGF.EmitDeleteCall(Dtor->getOperatorDelete(), 15810b57cec5SDimitry Andric LoadThisForDtorDelete(CGF, Dtor), 15820b57cec5SDimitry Andric CGF.getContext().getTagDeclType(ClassDecl)); 15830b57cec5SDimitry Andric } 15840b57cec5SDimitry Andric }; 15850b57cec5SDimitry Andric 15860b57cec5SDimitry Andric void EmitConditionalDtorDeleteCall(CodeGenFunction &CGF, 15870b57cec5SDimitry Andric llvm::Value *ShouldDeleteCondition, 15880b57cec5SDimitry Andric bool ReturnAfterDelete) { 15890b57cec5SDimitry Andric llvm::BasicBlock *callDeleteBB = CGF.createBasicBlock("dtor.call_delete"); 15900b57cec5SDimitry Andric llvm::BasicBlock *continueBB = CGF.createBasicBlock("dtor.continue"); 15910b57cec5SDimitry Andric llvm::Value *ShouldCallDelete 15920b57cec5SDimitry Andric = CGF.Builder.CreateIsNull(ShouldDeleteCondition); 15930b57cec5SDimitry Andric CGF.Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB); 15940b57cec5SDimitry Andric 15950b57cec5SDimitry Andric CGF.EmitBlock(callDeleteBB); 15960b57cec5SDimitry Andric const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 15970b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = Dtor->getParent(); 15980b57cec5SDimitry Andric CGF.EmitDeleteCall(Dtor->getOperatorDelete(), 15990b57cec5SDimitry Andric LoadThisForDtorDelete(CGF, Dtor), 16000b57cec5SDimitry Andric CGF.getContext().getTagDeclType(ClassDecl)); 16010b57cec5SDimitry Andric assert(Dtor->getOperatorDelete()->isDestroyingOperatorDelete() == 16020b57cec5SDimitry Andric ReturnAfterDelete && 16030b57cec5SDimitry Andric "unexpected value for ReturnAfterDelete"); 16040b57cec5SDimitry Andric if (ReturnAfterDelete) 16050b57cec5SDimitry Andric CGF.EmitBranchThroughCleanup(CGF.ReturnBlock); 16060b57cec5SDimitry Andric else 16070b57cec5SDimitry Andric CGF.Builder.CreateBr(continueBB); 16080b57cec5SDimitry Andric 16090b57cec5SDimitry Andric CGF.EmitBlock(continueBB); 16100b57cec5SDimitry Andric } 16110b57cec5SDimitry Andric 16120b57cec5SDimitry Andric struct CallDtorDeleteConditional final : EHScopeStack::Cleanup { 16130b57cec5SDimitry Andric llvm::Value *ShouldDeleteCondition; 16140b57cec5SDimitry Andric 16150b57cec5SDimitry Andric public: 16160b57cec5SDimitry Andric CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition) 16170b57cec5SDimitry Andric : ShouldDeleteCondition(ShouldDeleteCondition) { 16180b57cec5SDimitry Andric assert(ShouldDeleteCondition != nullptr); 16190b57cec5SDimitry Andric } 16200b57cec5SDimitry Andric 16210b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 16220b57cec5SDimitry Andric EmitConditionalDtorDeleteCall(CGF, ShouldDeleteCondition, 16230b57cec5SDimitry Andric /*ReturnAfterDelete*/false); 16240b57cec5SDimitry Andric } 16250b57cec5SDimitry Andric }; 16260b57cec5SDimitry Andric 16270b57cec5SDimitry Andric class DestroyField final : public EHScopeStack::Cleanup { 16280b57cec5SDimitry Andric const FieldDecl *field; 16290b57cec5SDimitry Andric CodeGenFunction::Destroyer *destroyer; 16300b57cec5SDimitry Andric bool useEHCleanupForArray; 16310b57cec5SDimitry Andric 16320b57cec5SDimitry Andric public: 16330b57cec5SDimitry Andric DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer, 16340b57cec5SDimitry Andric bool useEHCleanupForArray) 16350b57cec5SDimitry Andric : field(field), destroyer(destroyer), 16360b57cec5SDimitry Andric useEHCleanupForArray(useEHCleanupForArray) {} 16370b57cec5SDimitry Andric 16380b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 16390b57cec5SDimitry Andric // Find the address of the field. 16400b57cec5SDimitry Andric Address thisValue = CGF.LoadCXXThisAddress(); 16410b57cec5SDimitry Andric QualType RecordTy = CGF.getContext().getTagDeclType(field->getParent()); 16420b57cec5SDimitry Andric LValue ThisLV = CGF.MakeAddrLValue(thisValue, RecordTy); 16430b57cec5SDimitry Andric LValue LV = CGF.EmitLValueForField(ThisLV, field); 16440b57cec5SDimitry Andric assert(LV.isSimple()); 16450b57cec5SDimitry Andric 1646480093f4SDimitry Andric CGF.emitDestroy(LV.getAddress(CGF), field->getType(), destroyer, 16470b57cec5SDimitry Andric flags.isForNormalCleanup() && useEHCleanupForArray); 16480b57cec5SDimitry Andric } 16490b57cec5SDimitry Andric }; 16500b57cec5SDimitry Andric 16510b57cec5SDimitry Andric static void EmitSanitizerDtorCallback(CodeGenFunction &CGF, llvm::Value *Ptr, 16520b57cec5SDimitry Andric CharUnits::QuantityType PoisonSize) { 16530b57cec5SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF); 16540b57cec5SDimitry Andric // Pass in void pointer and size of region as arguments to runtime 16550b57cec5SDimitry Andric // function 16560b57cec5SDimitry Andric llvm::Value *Args[] = {CGF.Builder.CreateBitCast(Ptr, CGF.VoidPtrTy), 16570b57cec5SDimitry Andric llvm::ConstantInt::get(CGF.SizeTy, PoisonSize)}; 16580b57cec5SDimitry Andric 16590b57cec5SDimitry Andric llvm::Type *ArgTypes[] = {CGF.VoidPtrTy, CGF.SizeTy}; 16600b57cec5SDimitry Andric 16610b57cec5SDimitry Andric llvm::FunctionType *FnType = 16620b57cec5SDimitry Andric llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false); 16630b57cec5SDimitry Andric llvm::FunctionCallee Fn = 16640b57cec5SDimitry Andric CGF.CGM.CreateRuntimeFunction(FnType, "__sanitizer_dtor_callback"); 16650b57cec5SDimitry Andric CGF.EmitNounwindRuntimeCall(Fn, Args); 16660b57cec5SDimitry Andric } 16670b57cec5SDimitry Andric 16680b57cec5SDimitry Andric class SanitizeDtorMembers final : public EHScopeStack::Cleanup { 16690b57cec5SDimitry Andric const CXXDestructorDecl *Dtor; 16700b57cec5SDimitry Andric 16710b57cec5SDimitry Andric public: 16720b57cec5SDimitry Andric SanitizeDtorMembers(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {} 16730b57cec5SDimitry Andric 16740b57cec5SDimitry Andric // Generate function call for handling object poisoning. 16750b57cec5SDimitry Andric // Disables tail call elimination, to prevent the current stack frame 16760b57cec5SDimitry Andric // from disappearing from the stack trace. 16770b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 16780b57cec5SDimitry Andric const ASTRecordLayout &Layout = 16790b57cec5SDimitry Andric CGF.getContext().getASTRecordLayout(Dtor->getParent()); 16800b57cec5SDimitry Andric 16810b57cec5SDimitry Andric // Nothing to poison. 16820b57cec5SDimitry Andric if (Layout.getFieldCount() == 0) 16830b57cec5SDimitry Andric return; 16840b57cec5SDimitry Andric 16850b57cec5SDimitry Andric // Prevent the current stack frame from disappearing from the stack trace. 16860b57cec5SDimitry Andric CGF.CurFn->addFnAttr("disable-tail-calls", "true"); 16870b57cec5SDimitry Andric 16880b57cec5SDimitry Andric // Construct pointer to region to begin poisoning, and calculate poison 16890b57cec5SDimitry Andric // size, so that only members declared in this class are poisoned. 16900b57cec5SDimitry Andric ASTContext &Context = CGF.getContext(); 16910b57cec5SDimitry Andric 1692e8d8bef9SDimitry Andric const RecordDecl *Decl = Dtor->getParent(); 1693e8d8bef9SDimitry Andric auto Fields = Decl->fields(); 1694e8d8bef9SDimitry Andric auto IsTrivial = [&](const FieldDecl *F) { 1695e8d8bef9SDimitry Andric return FieldHasTrivialDestructorBody(Context, F); 1696e8d8bef9SDimitry Andric }; 1697e8d8bef9SDimitry Andric 1698e8d8bef9SDimitry Andric auto IsZeroSize = [&](const FieldDecl *F) { 1699e8d8bef9SDimitry Andric return F->isZeroSize(Context); 1700e8d8bef9SDimitry Andric }; 1701e8d8bef9SDimitry Andric 1702e8d8bef9SDimitry Andric // Poison blocks of fields with trivial destructors making sure that block 1703e8d8bef9SDimitry Andric // begin and end do not point to zero-sized fields. They don't have 1704e8d8bef9SDimitry Andric // correct offsets so can't be used to calculate poisoning range. 1705e8d8bef9SDimitry Andric for (auto It = Fields.begin(); It != Fields.end();) { 1706e8d8bef9SDimitry Andric It = std::find_if(It, Fields.end(), [&](const FieldDecl *F) { 1707e8d8bef9SDimitry Andric return IsTrivial(F) && !IsZeroSize(F); 1708e8d8bef9SDimitry Andric }); 1709e8d8bef9SDimitry Andric if (It == Fields.end()) 1710e8d8bef9SDimitry Andric break; 1711e8d8bef9SDimitry Andric auto Start = It++; 1712e8d8bef9SDimitry Andric It = std::find_if(It, Fields.end(), [&](const FieldDecl *F) { 1713e8d8bef9SDimitry Andric return !IsTrivial(F) && !IsZeroSize(F); 1714e8d8bef9SDimitry Andric }); 1715e8d8bef9SDimitry Andric 1716e8d8bef9SDimitry Andric PoisonMembers(CGF, (*Start)->getFieldIndex(), 1717e8d8bef9SDimitry Andric It == Fields.end() ? -1 : (*It)->getFieldIndex()); 17180b57cec5SDimitry Andric } 17190b57cec5SDimitry Andric } 17200b57cec5SDimitry Andric 17210b57cec5SDimitry Andric private: 17220b57cec5SDimitry Andric /// \param layoutStartOffset index of the ASTRecordLayout field to 17230b57cec5SDimitry Andric /// start poisoning (inclusive) 17240b57cec5SDimitry Andric /// \param layoutEndOffset index of the ASTRecordLayout field to 17250b57cec5SDimitry Andric /// end poisoning (exclusive) 17260b57cec5SDimitry Andric void PoisonMembers(CodeGenFunction &CGF, unsigned layoutStartOffset, 17270b57cec5SDimitry Andric unsigned layoutEndOffset) { 17280b57cec5SDimitry Andric ASTContext &Context = CGF.getContext(); 17290b57cec5SDimitry Andric const ASTRecordLayout &Layout = 17300b57cec5SDimitry Andric Context.getASTRecordLayout(Dtor->getParent()); 17310b57cec5SDimitry Andric 1732e8d8bef9SDimitry Andric // It's a first trivia field so it should be at the begining of char, 1733e8d8bef9SDimitry Andric // still round up start offset just in case. 1734e8d8bef9SDimitry Andric CharUnits PoisonStart = 1735e8d8bef9SDimitry Andric Context.toCharUnitsFromBits(Layout.getFieldOffset(layoutStartOffset) + 1736e8d8bef9SDimitry Andric Context.getCharWidth() - 1); 1737e8d8bef9SDimitry Andric llvm::ConstantInt *OffsetSizePtr = 1738e8d8bef9SDimitry Andric llvm::ConstantInt::get(CGF.SizeTy, PoisonStart.getQuantity()); 17390b57cec5SDimitry Andric 17400b57cec5SDimitry Andric llvm::Value *OffsetPtr = CGF.Builder.CreateGEP( 1741fe6060f1SDimitry Andric CGF.Int8Ty, 17420b57cec5SDimitry Andric CGF.Builder.CreateBitCast(CGF.LoadCXXThis(), CGF.Int8PtrTy), 17430b57cec5SDimitry Andric OffsetSizePtr); 17440b57cec5SDimitry Andric 1745e8d8bef9SDimitry Andric CharUnits PoisonEnd; 17460b57cec5SDimitry Andric if (layoutEndOffset >= Layout.getFieldCount()) { 1747e8d8bef9SDimitry Andric PoisonEnd = Layout.getNonVirtualSize(); 17480b57cec5SDimitry Andric } else { 1749e8d8bef9SDimitry Andric PoisonEnd = 1750e8d8bef9SDimitry Andric Context.toCharUnitsFromBits(Layout.getFieldOffset(layoutEndOffset)); 17510b57cec5SDimitry Andric } 1752e8d8bef9SDimitry Andric CharUnits PoisonSize = PoisonEnd - PoisonStart; 1753e8d8bef9SDimitry Andric if (!PoisonSize.isPositive()) 17540b57cec5SDimitry Andric return; 17550b57cec5SDimitry Andric 1756e8d8bef9SDimitry Andric EmitSanitizerDtorCallback(CGF, OffsetPtr, PoisonSize.getQuantity()); 17570b57cec5SDimitry Andric } 17580b57cec5SDimitry Andric }; 17590b57cec5SDimitry Andric 17600b57cec5SDimitry Andric class SanitizeDtorVTable final : public EHScopeStack::Cleanup { 17610b57cec5SDimitry Andric const CXXDestructorDecl *Dtor; 17620b57cec5SDimitry Andric 17630b57cec5SDimitry Andric public: 17640b57cec5SDimitry Andric SanitizeDtorVTable(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {} 17650b57cec5SDimitry Andric 17660b57cec5SDimitry Andric // Generate function call for handling vtable pointer poisoning. 17670b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 17680b57cec5SDimitry Andric assert(Dtor->getParent()->isDynamicClass()); 17690b57cec5SDimitry Andric (void)Dtor; 17700b57cec5SDimitry Andric ASTContext &Context = CGF.getContext(); 17710b57cec5SDimitry Andric // Poison vtable and vtable ptr if they exist for this class. 17720b57cec5SDimitry Andric llvm::Value *VTablePtr = CGF.LoadCXXThis(); 17730b57cec5SDimitry Andric 17740b57cec5SDimitry Andric CharUnits::QuantityType PoisonSize = 17750b57cec5SDimitry Andric Context.toCharUnitsFromBits(CGF.PointerWidthInBits).getQuantity(); 17760b57cec5SDimitry Andric // Pass in void pointer and size of region as arguments to runtime 17770b57cec5SDimitry Andric // function 17780b57cec5SDimitry Andric EmitSanitizerDtorCallback(CGF, VTablePtr, PoisonSize); 17790b57cec5SDimitry Andric } 17800b57cec5SDimitry Andric }; 17810b57cec5SDimitry Andric } // end anonymous namespace 17820b57cec5SDimitry Andric 17830b57cec5SDimitry Andric /// Emit all code that comes at the end of class's 17840b57cec5SDimitry Andric /// destructor. This is to call destructors on members and base classes 17850b57cec5SDimitry Andric /// in reverse order of their construction. 17860b57cec5SDimitry Andric /// 17870b57cec5SDimitry Andric /// For a deleting destructor, this also handles the case where a destroying 17880b57cec5SDimitry Andric /// operator delete completely overrides the definition. 17890b57cec5SDimitry Andric void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, 17900b57cec5SDimitry Andric CXXDtorType DtorType) { 17910b57cec5SDimitry Andric assert((!DD->isTrivial() || DD->hasAttr<DLLExportAttr>()) && 17920b57cec5SDimitry Andric "Should not emit dtor epilogue for non-exported trivial dtor!"); 17930b57cec5SDimitry Andric 17940b57cec5SDimitry Andric // The deleting-destructor phase just needs to call the appropriate 17950b57cec5SDimitry Andric // operator delete that Sema picked up. 17960b57cec5SDimitry Andric if (DtorType == Dtor_Deleting) { 17970b57cec5SDimitry Andric assert(DD->getOperatorDelete() && 17980b57cec5SDimitry Andric "operator delete missing - EnterDtorCleanups"); 17990b57cec5SDimitry Andric if (CXXStructorImplicitParamValue) { 18000b57cec5SDimitry Andric // If there is an implicit param to the deleting dtor, it's a boolean 18010b57cec5SDimitry Andric // telling whether this is a deleting destructor. 18020b57cec5SDimitry Andric if (DD->getOperatorDelete()->isDestroyingOperatorDelete()) 18030b57cec5SDimitry Andric EmitConditionalDtorDeleteCall(*this, CXXStructorImplicitParamValue, 18040b57cec5SDimitry Andric /*ReturnAfterDelete*/true); 18050b57cec5SDimitry Andric else 18060b57cec5SDimitry Andric EHStack.pushCleanup<CallDtorDeleteConditional>( 18070b57cec5SDimitry Andric NormalAndEHCleanup, CXXStructorImplicitParamValue); 18080b57cec5SDimitry Andric } else { 18090b57cec5SDimitry Andric if (DD->getOperatorDelete()->isDestroyingOperatorDelete()) { 18100b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = DD->getParent(); 18110b57cec5SDimitry Andric EmitDeleteCall(DD->getOperatorDelete(), 18120b57cec5SDimitry Andric LoadThisForDtorDelete(*this, DD), 18130b57cec5SDimitry Andric getContext().getTagDeclType(ClassDecl)); 18140b57cec5SDimitry Andric EmitBranchThroughCleanup(ReturnBlock); 18150b57cec5SDimitry Andric } else { 18160b57cec5SDimitry Andric EHStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup); 18170b57cec5SDimitry Andric } 18180b57cec5SDimitry Andric } 18190b57cec5SDimitry Andric return; 18200b57cec5SDimitry Andric } 18210b57cec5SDimitry Andric 18220b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = DD->getParent(); 18230b57cec5SDimitry Andric 18240b57cec5SDimitry Andric // Unions have no bases and do not call field destructors. 18250b57cec5SDimitry Andric if (ClassDecl->isUnion()) 18260b57cec5SDimitry Andric return; 18270b57cec5SDimitry Andric 18280b57cec5SDimitry Andric // The complete-destructor phase just destructs all the virtual bases. 18290b57cec5SDimitry Andric if (DtorType == Dtor_Complete) { 18300b57cec5SDimitry Andric // Poison the vtable pointer such that access after the base 18310b57cec5SDimitry Andric // and member destructors are invoked is invalid. 18320b57cec5SDimitry Andric if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor && 18330b57cec5SDimitry Andric SanOpts.has(SanitizerKind::Memory) && ClassDecl->getNumVBases() && 18340b57cec5SDimitry Andric ClassDecl->isPolymorphic()) 18350b57cec5SDimitry Andric EHStack.pushCleanup<SanitizeDtorVTable>(NormalAndEHCleanup, DD); 18360b57cec5SDimitry Andric 18370b57cec5SDimitry Andric // We push them in the forward order so that they'll be popped in 18380b57cec5SDimitry Andric // the reverse order. 18390b57cec5SDimitry Andric for (const auto &Base : ClassDecl->vbases()) { 1840a7dea167SDimitry Andric auto *BaseClassDecl = 1841a7dea167SDimitry Andric cast<CXXRecordDecl>(Base.getType()->castAs<RecordType>()->getDecl()); 18420b57cec5SDimitry Andric 18430b57cec5SDimitry Andric // Ignore trivial destructors. 18440b57cec5SDimitry Andric if (BaseClassDecl->hasTrivialDestructor()) 18450b57cec5SDimitry Andric continue; 18460b57cec5SDimitry Andric 18470b57cec5SDimitry Andric EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 18480b57cec5SDimitry Andric BaseClassDecl, 18490b57cec5SDimitry Andric /*BaseIsVirtual*/ true); 18500b57cec5SDimitry Andric } 18510b57cec5SDimitry Andric 18520b57cec5SDimitry Andric return; 18530b57cec5SDimitry Andric } 18540b57cec5SDimitry Andric 18550b57cec5SDimitry Andric assert(DtorType == Dtor_Base); 18560b57cec5SDimitry Andric // Poison the vtable pointer if it has no virtual bases, but inherits 18570b57cec5SDimitry Andric // virtual functions. 18580b57cec5SDimitry Andric if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor && 18590b57cec5SDimitry Andric SanOpts.has(SanitizerKind::Memory) && !ClassDecl->getNumVBases() && 18600b57cec5SDimitry Andric ClassDecl->isPolymorphic()) 18610b57cec5SDimitry Andric EHStack.pushCleanup<SanitizeDtorVTable>(NormalAndEHCleanup, DD); 18620b57cec5SDimitry Andric 18630b57cec5SDimitry Andric // Destroy non-virtual bases. 18640b57cec5SDimitry Andric for (const auto &Base : ClassDecl->bases()) { 18650b57cec5SDimitry Andric // Ignore virtual bases. 18660b57cec5SDimitry Andric if (Base.isVirtual()) 18670b57cec5SDimitry Andric continue; 18680b57cec5SDimitry Andric 18690b57cec5SDimitry Andric CXXRecordDecl *BaseClassDecl = Base.getType()->getAsCXXRecordDecl(); 18700b57cec5SDimitry Andric 18710b57cec5SDimitry Andric // Ignore trivial destructors. 18720b57cec5SDimitry Andric if (BaseClassDecl->hasTrivialDestructor()) 18730b57cec5SDimitry Andric continue; 18740b57cec5SDimitry Andric 18750b57cec5SDimitry Andric EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, 18760b57cec5SDimitry Andric BaseClassDecl, 18770b57cec5SDimitry Andric /*BaseIsVirtual*/ false); 18780b57cec5SDimitry Andric } 18790b57cec5SDimitry Andric 18800b57cec5SDimitry Andric // Poison fields such that access after their destructors are 18810b57cec5SDimitry Andric // invoked, and before the base class destructor runs, is invalid. 18820b57cec5SDimitry Andric if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor && 18830b57cec5SDimitry Andric SanOpts.has(SanitizerKind::Memory)) 18840b57cec5SDimitry Andric EHStack.pushCleanup<SanitizeDtorMembers>(NormalAndEHCleanup, DD); 18850b57cec5SDimitry Andric 18860b57cec5SDimitry Andric // Destroy direct fields. 18870b57cec5SDimitry Andric for (const auto *Field : ClassDecl->fields()) { 18880b57cec5SDimitry Andric QualType type = Field->getType(); 18890b57cec5SDimitry Andric QualType::DestructionKind dtorKind = type.isDestructedType(); 18900b57cec5SDimitry Andric if (!dtorKind) continue; 18910b57cec5SDimitry Andric 18920b57cec5SDimitry Andric // Anonymous union members do not have their destructors called. 18930b57cec5SDimitry Andric const RecordType *RT = type->getAsUnionType(); 18940b57cec5SDimitry Andric if (RT && RT->getDecl()->isAnonymousStructOrUnion()) continue; 18950b57cec5SDimitry Andric 18960b57cec5SDimitry Andric CleanupKind cleanupKind = getCleanupKind(dtorKind); 18970b57cec5SDimitry Andric EHStack.pushCleanup<DestroyField>(cleanupKind, Field, 18980b57cec5SDimitry Andric getDestroyer(dtorKind), 18990b57cec5SDimitry Andric cleanupKind & EHCleanup); 19000b57cec5SDimitry Andric } 19010b57cec5SDimitry Andric } 19020b57cec5SDimitry Andric 19030b57cec5SDimitry Andric /// EmitCXXAggrConstructorCall - Emit a loop to call a particular 19040b57cec5SDimitry Andric /// constructor for each of several members of an array. 19050b57cec5SDimitry Andric /// 19060b57cec5SDimitry Andric /// \param ctor the constructor to call for each element 19070b57cec5SDimitry Andric /// \param arrayType the type of the array to initialize 19080b57cec5SDimitry Andric /// \param arrayBegin an arrayType* 19090b57cec5SDimitry Andric /// \param zeroInitialize true if each element should be 19100b57cec5SDimitry Andric /// zero-initialized before it is constructed 19110b57cec5SDimitry Andric void CodeGenFunction::EmitCXXAggrConstructorCall( 19120b57cec5SDimitry Andric const CXXConstructorDecl *ctor, const ArrayType *arrayType, 19130b57cec5SDimitry Andric Address arrayBegin, const CXXConstructExpr *E, bool NewPointerIsChecked, 19140b57cec5SDimitry Andric bool zeroInitialize) { 19150b57cec5SDimitry Andric QualType elementType; 19160b57cec5SDimitry Andric llvm::Value *numElements = 19170b57cec5SDimitry Andric emitArrayLength(arrayType, elementType, arrayBegin); 19180b57cec5SDimitry Andric 19190b57cec5SDimitry Andric EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, E, 19200b57cec5SDimitry Andric NewPointerIsChecked, zeroInitialize); 19210b57cec5SDimitry Andric } 19220b57cec5SDimitry Andric 19230b57cec5SDimitry Andric /// EmitCXXAggrConstructorCall - Emit a loop to call a particular 19240b57cec5SDimitry Andric /// constructor for each of several members of an array. 19250b57cec5SDimitry Andric /// 19260b57cec5SDimitry Andric /// \param ctor the constructor to call for each element 19270b57cec5SDimitry Andric /// \param numElements the number of elements in the array; 19280b57cec5SDimitry Andric /// may be zero 19290b57cec5SDimitry Andric /// \param arrayBase a T*, where T is the type constructed by ctor 19300b57cec5SDimitry Andric /// \param zeroInitialize true if each element should be 19310b57cec5SDimitry Andric /// zero-initialized before it is constructed 19320b57cec5SDimitry Andric void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 19330b57cec5SDimitry Andric llvm::Value *numElements, 19340b57cec5SDimitry Andric Address arrayBase, 19350b57cec5SDimitry Andric const CXXConstructExpr *E, 19360b57cec5SDimitry Andric bool NewPointerIsChecked, 19370b57cec5SDimitry Andric bool zeroInitialize) { 19380b57cec5SDimitry Andric // It's legal for numElements to be zero. This can happen both 19390b57cec5SDimitry Andric // dynamically, because x can be zero in 'new A[x]', and statically, 19400b57cec5SDimitry Andric // because of GCC extensions that permit zero-length arrays. There 19410b57cec5SDimitry Andric // are probably legitimate places where we could assume that this 19420b57cec5SDimitry Andric // doesn't happen, but it's not clear that it's worth it. 19430b57cec5SDimitry Andric llvm::BranchInst *zeroCheckBranch = nullptr; 19440b57cec5SDimitry Andric 19450b57cec5SDimitry Andric // Optimize for a constant count. 19460b57cec5SDimitry Andric llvm::ConstantInt *constantCount 19470b57cec5SDimitry Andric = dyn_cast<llvm::ConstantInt>(numElements); 19480b57cec5SDimitry Andric if (constantCount) { 19490b57cec5SDimitry Andric // Just skip out if the constant count is zero. 19500b57cec5SDimitry Andric if (constantCount->isZero()) return; 19510b57cec5SDimitry Andric 19520b57cec5SDimitry Andric // Otherwise, emit the check. 19530b57cec5SDimitry Andric } else { 19540b57cec5SDimitry Andric llvm::BasicBlock *loopBB = createBasicBlock("new.ctorloop"); 19550b57cec5SDimitry Andric llvm::Value *iszero = Builder.CreateIsNull(numElements, "isempty"); 19560b57cec5SDimitry Andric zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB); 19570b57cec5SDimitry Andric EmitBlock(loopBB); 19580b57cec5SDimitry Andric } 19590b57cec5SDimitry Andric 19600b57cec5SDimitry Andric // Find the end of the array. 1961fe6060f1SDimitry Andric llvm::Type *elementType = arrayBase.getElementType(); 19620b57cec5SDimitry Andric llvm::Value *arrayBegin = arrayBase.getPointer(); 1963fe6060f1SDimitry Andric llvm::Value *arrayEnd = Builder.CreateInBoundsGEP( 1964fe6060f1SDimitry Andric elementType, arrayBegin, numElements, "arrayctor.end"); 19650b57cec5SDimitry Andric 19660b57cec5SDimitry Andric // Enter the loop, setting up a phi for the current location to initialize. 19670b57cec5SDimitry Andric llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); 19680b57cec5SDimitry Andric llvm::BasicBlock *loopBB = createBasicBlock("arrayctor.loop"); 19690b57cec5SDimitry Andric EmitBlock(loopBB); 19700b57cec5SDimitry Andric llvm::PHINode *cur = Builder.CreatePHI(arrayBegin->getType(), 2, 19710b57cec5SDimitry Andric "arrayctor.cur"); 19720b57cec5SDimitry Andric cur->addIncoming(arrayBegin, entryBB); 19730b57cec5SDimitry Andric 19740b57cec5SDimitry Andric // Inside the loop body, emit the constructor call on the array element. 19750b57cec5SDimitry Andric 19760b57cec5SDimitry Andric // The alignment of the base, adjusted by the size of a single element, 19770b57cec5SDimitry Andric // provides a conservative estimate of the alignment of every element. 19780b57cec5SDimitry Andric // (This assumes we never start tracking offsetted alignments.) 19790b57cec5SDimitry Andric // 19800b57cec5SDimitry Andric // Note that these are complete objects and so we don't need to 19810b57cec5SDimitry Andric // use the non-virtual size or alignment. 19820b57cec5SDimitry Andric QualType type = getContext().getTypeDeclType(ctor->getParent()); 19830b57cec5SDimitry Andric CharUnits eltAlignment = 19840b57cec5SDimitry Andric arrayBase.getAlignment() 19850b57cec5SDimitry Andric .alignmentOfArrayElement(getContext().getTypeSizeInChars(type)); 198604eeddc0SDimitry Andric Address curAddr = Address(cur, elementType, eltAlignment); 19870b57cec5SDimitry Andric 19880b57cec5SDimitry Andric // Zero initialize the storage, if requested. 19890b57cec5SDimitry Andric if (zeroInitialize) 19900b57cec5SDimitry Andric EmitNullInitialization(curAddr, type); 19910b57cec5SDimitry Andric 19920b57cec5SDimitry Andric // C++ [class.temporary]p4: 19930b57cec5SDimitry Andric // There are two contexts in which temporaries are destroyed at a different 19940b57cec5SDimitry Andric // point than the end of the full-expression. The first context is when a 19950b57cec5SDimitry Andric // default constructor is called to initialize an element of an array. 19960b57cec5SDimitry Andric // If the constructor has one or more default arguments, the destruction of 19970b57cec5SDimitry Andric // every temporary created in a default argument expression is sequenced 19980b57cec5SDimitry Andric // before the construction of the next array element, if any. 19990b57cec5SDimitry Andric 20000b57cec5SDimitry Andric { 20010b57cec5SDimitry Andric RunCleanupsScope Scope(*this); 20020b57cec5SDimitry Andric 20030b57cec5SDimitry Andric // Evaluate the constructor and its arguments in a regular 20040b57cec5SDimitry Andric // partial-destroy cleanup. 20050b57cec5SDimitry Andric if (getLangOpts().Exceptions && 20060b57cec5SDimitry Andric !ctor->getParent()->hasTrivialDestructor()) { 20070b57cec5SDimitry Andric Destroyer *destroyer = destroyCXXObject; 20080b57cec5SDimitry Andric pushRegularPartialArrayCleanup(arrayBegin, cur, type, eltAlignment, 20090b57cec5SDimitry Andric *destroyer); 20100b57cec5SDimitry Andric } 20110b57cec5SDimitry Andric auto currAVS = AggValueSlot::forAddr( 20120b57cec5SDimitry Andric curAddr, type.getQualifiers(), AggValueSlot::IsDestructed, 20130b57cec5SDimitry Andric AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, 20140b57cec5SDimitry Andric AggValueSlot::DoesNotOverlap, AggValueSlot::IsNotZeroed, 20150b57cec5SDimitry Andric NewPointerIsChecked ? AggValueSlot::IsSanitizerChecked 20160b57cec5SDimitry Andric : AggValueSlot::IsNotSanitizerChecked); 20170b57cec5SDimitry Andric EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/false, 20180b57cec5SDimitry Andric /*Delegating=*/false, currAVS, E); 20190b57cec5SDimitry Andric } 20200b57cec5SDimitry Andric 20210b57cec5SDimitry Andric // Go to the next element. 2022fe6060f1SDimitry Andric llvm::Value *next = Builder.CreateInBoundsGEP( 2023fe6060f1SDimitry Andric elementType, cur, llvm::ConstantInt::get(SizeTy, 1), "arrayctor.next"); 20240b57cec5SDimitry Andric cur->addIncoming(next, Builder.GetInsertBlock()); 20250b57cec5SDimitry Andric 20260b57cec5SDimitry Andric // Check whether that's the end of the loop. 20270b57cec5SDimitry Andric llvm::Value *done = Builder.CreateICmpEQ(next, arrayEnd, "arrayctor.done"); 20280b57cec5SDimitry Andric llvm::BasicBlock *contBB = createBasicBlock("arrayctor.cont"); 20290b57cec5SDimitry Andric Builder.CreateCondBr(done, contBB, loopBB); 20300b57cec5SDimitry Andric 20310b57cec5SDimitry Andric // Patch the earlier check to skip over the loop. 20320b57cec5SDimitry Andric if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB); 20330b57cec5SDimitry Andric 20340b57cec5SDimitry Andric EmitBlock(contBB); 20350b57cec5SDimitry Andric } 20360b57cec5SDimitry Andric 20370b57cec5SDimitry Andric void CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF, 20380b57cec5SDimitry Andric Address addr, 20390b57cec5SDimitry Andric QualType type) { 20400b57cec5SDimitry Andric const RecordType *rtype = type->castAs<RecordType>(); 20410b57cec5SDimitry Andric const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl()); 20420b57cec5SDimitry Andric const CXXDestructorDecl *dtor = record->getDestructor(); 20430b57cec5SDimitry Andric assert(!dtor->isTrivial()); 20440b57cec5SDimitry Andric CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false, 20450b57cec5SDimitry Andric /*Delegating=*/false, addr, type); 20460b57cec5SDimitry Andric } 20470b57cec5SDimitry Andric 20480b57cec5SDimitry Andric void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 20490b57cec5SDimitry Andric CXXCtorType Type, 20500b57cec5SDimitry Andric bool ForVirtualBase, 20510b57cec5SDimitry Andric bool Delegating, 20520b57cec5SDimitry Andric AggValueSlot ThisAVS, 20530b57cec5SDimitry Andric const CXXConstructExpr *E) { 20540b57cec5SDimitry Andric CallArgList Args; 20550b57cec5SDimitry Andric Address This = ThisAVS.getAddress(); 20560b57cec5SDimitry Andric LangAS SlotAS = ThisAVS.getQualifiers().getAddressSpace(); 20570b57cec5SDimitry Andric QualType ThisType = D->getThisType(); 20580b57cec5SDimitry Andric LangAS ThisAS = ThisType.getTypePtr()->getPointeeType().getAddressSpace(); 20590b57cec5SDimitry Andric llvm::Value *ThisPtr = This.getPointer(); 20600b57cec5SDimitry Andric 20610b57cec5SDimitry Andric if (SlotAS != ThisAS) { 20620b57cec5SDimitry Andric unsigned TargetThisAS = getContext().getTargetAddressSpace(ThisAS); 20630eae32dcSDimitry Andric llvm::Type *NewType = llvm::PointerType::getWithSamePointeeType( 20640eae32dcSDimitry Andric This.getType(), TargetThisAS); 20650b57cec5SDimitry Andric ThisPtr = getTargetHooks().performAddrSpaceCast(*this, This.getPointer(), 20660b57cec5SDimitry Andric ThisAS, SlotAS, NewType); 20670b57cec5SDimitry Andric } 20680b57cec5SDimitry Andric 20690b57cec5SDimitry Andric // Push the this ptr. 20700b57cec5SDimitry Andric Args.add(RValue::get(ThisPtr), D->getThisType()); 20710b57cec5SDimitry Andric 20720b57cec5SDimitry Andric // If this is a trivial constructor, emit a memcpy now before we lose 20730b57cec5SDimitry Andric // the alignment information on the argument. 20740b57cec5SDimitry Andric // FIXME: It would be better to preserve alignment information into CallArg. 20750b57cec5SDimitry Andric if (isMemcpyEquivalentSpecialMember(D)) { 20760b57cec5SDimitry Andric assert(E->getNumArgs() == 1 && "unexpected argcount for trivial ctor"); 20770b57cec5SDimitry Andric 20780b57cec5SDimitry Andric const Expr *Arg = E->getArg(0); 20790b57cec5SDimitry Andric LValue Src = EmitLValue(Arg); 20800b57cec5SDimitry Andric QualType DestTy = getContext().getTypeDeclType(D->getParent()); 20810b57cec5SDimitry Andric LValue Dest = MakeAddrLValue(This, DestTy); 20820b57cec5SDimitry Andric EmitAggregateCopyCtor(Dest, Src, ThisAVS.mayOverlap()); 20830b57cec5SDimitry Andric return; 20840b57cec5SDimitry Andric } 20850b57cec5SDimitry Andric 20860b57cec5SDimitry Andric // Add the rest of the user-supplied arguments. 20870b57cec5SDimitry Andric const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>(); 20880b57cec5SDimitry Andric EvaluationOrder Order = E->isListInitialization() 20890b57cec5SDimitry Andric ? EvaluationOrder::ForceLeftToRight 20900b57cec5SDimitry Andric : EvaluationOrder::Default; 20910b57cec5SDimitry Andric EmitCallArgs(Args, FPT, E->arguments(), E->getConstructor(), 20920b57cec5SDimitry Andric /*ParamsToSkip*/ 0, Order); 20930b57cec5SDimitry Andric 20940b57cec5SDimitry Andric EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args, 20950b57cec5SDimitry Andric ThisAVS.mayOverlap(), E->getExprLoc(), 20960b57cec5SDimitry Andric ThisAVS.isSanitizerChecked()); 20970b57cec5SDimitry Andric } 20980b57cec5SDimitry Andric 20990b57cec5SDimitry Andric static bool canEmitDelegateCallArgs(CodeGenFunction &CGF, 21000b57cec5SDimitry Andric const CXXConstructorDecl *Ctor, 21010b57cec5SDimitry Andric CXXCtorType Type, CallArgList &Args) { 21020b57cec5SDimitry Andric // We can't forward a variadic call. 21030b57cec5SDimitry Andric if (Ctor->isVariadic()) 21040b57cec5SDimitry Andric return false; 21050b57cec5SDimitry Andric 21060b57cec5SDimitry Andric if (CGF.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) { 21070b57cec5SDimitry Andric // If the parameters are callee-cleanup, it's not safe to forward. 21080b57cec5SDimitry Andric for (auto *P : Ctor->parameters()) 2109a7dea167SDimitry Andric if (P->needsDestruction(CGF.getContext())) 21100b57cec5SDimitry Andric return false; 21110b57cec5SDimitry Andric 21120b57cec5SDimitry Andric // Likewise if they're inalloca. 21130b57cec5SDimitry Andric const CGFunctionInfo &Info = 21140b57cec5SDimitry Andric CGF.CGM.getTypes().arrangeCXXConstructorCall(Args, Ctor, Type, 0, 0); 21150b57cec5SDimitry Andric if (Info.usesInAlloca()) 21160b57cec5SDimitry Andric return false; 21170b57cec5SDimitry Andric } 21180b57cec5SDimitry Andric 21190b57cec5SDimitry Andric // Anything else should be OK. 21200b57cec5SDimitry Andric return true; 21210b57cec5SDimitry Andric } 21220b57cec5SDimitry Andric 21230b57cec5SDimitry Andric void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 21240b57cec5SDimitry Andric CXXCtorType Type, 21250b57cec5SDimitry Andric bool ForVirtualBase, 21260b57cec5SDimitry Andric bool Delegating, 21270b57cec5SDimitry Andric Address This, 21280b57cec5SDimitry Andric CallArgList &Args, 21290b57cec5SDimitry Andric AggValueSlot::Overlap_t Overlap, 21300b57cec5SDimitry Andric SourceLocation Loc, 21310b57cec5SDimitry Andric bool NewPointerIsChecked) { 21320b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = D->getParent(); 21330b57cec5SDimitry Andric 21340b57cec5SDimitry Andric if (!NewPointerIsChecked) 21350b57cec5SDimitry Andric EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, Loc, This.getPointer(), 21360b57cec5SDimitry Andric getContext().getRecordType(ClassDecl), CharUnits::Zero()); 21370b57cec5SDimitry Andric 21380b57cec5SDimitry Andric if (D->isTrivial() && D->isDefaultConstructor()) { 21390b57cec5SDimitry Andric assert(Args.size() == 1 && "trivial default ctor with args"); 21400b57cec5SDimitry Andric return; 21410b57cec5SDimitry Andric } 21420b57cec5SDimitry Andric 21430b57cec5SDimitry Andric // If this is a trivial constructor, just emit what's needed. If this is a 21440b57cec5SDimitry Andric // union copy constructor, we must emit a memcpy, because the AST does not 21450b57cec5SDimitry Andric // model that copy. 21460b57cec5SDimitry Andric if (isMemcpyEquivalentSpecialMember(D)) { 21470b57cec5SDimitry Andric assert(Args.size() == 2 && "unexpected argcount for trivial ctor"); 21480b57cec5SDimitry Andric 21490b57cec5SDimitry Andric QualType SrcTy = D->getParamDecl(0)->getType().getNonReferenceType(); 21500b57cec5SDimitry Andric Address Src(Args[1].getRValue(*this).getScalarVal(), 21515ffd83dbSDimitry Andric CGM.getNaturalTypeAlignment(SrcTy)); 21520b57cec5SDimitry Andric LValue SrcLVal = MakeAddrLValue(Src, SrcTy); 21530b57cec5SDimitry Andric QualType DestTy = getContext().getTypeDeclType(ClassDecl); 21540b57cec5SDimitry Andric LValue DestLVal = MakeAddrLValue(This, DestTy); 21550b57cec5SDimitry Andric EmitAggregateCopyCtor(DestLVal, SrcLVal, Overlap); 21560b57cec5SDimitry Andric return; 21570b57cec5SDimitry Andric } 21580b57cec5SDimitry Andric 21590b57cec5SDimitry Andric bool PassPrototypeArgs = true; 21600b57cec5SDimitry Andric // Check whether we can actually emit the constructor before trying to do so. 21610b57cec5SDimitry Andric if (auto Inherited = D->getInheritedConstructor()) { 21620b57cec5SDimitry Andric PassPrototypeArgs = getTypes().inheritingCtorHasParams(Inherited, Type); 21630b57cec5SDimitry Andric if (PassPrototypeArgs && !canEmitDelegateCallArgs(*this, D, Type, Args)) { 21640b57cec5SDimitry Andric EmitInlinedInheritingCXXConstructorCall(D, Type, ForVirtualBase, 21650b57cec5SDimitry Andric Delegating, Args); 21660b57cec5SDimitry Andric return; 21670b57cec5SDimitry Andric } 21680b57cec5SDimitry Andric } 21690b57cec5SDimitry Andric 21700b57cec5SDimitry Andric // Insert any ABI-specific implicit constructor arguments. 21715ffd83dbSDimitry Andric CGCXXABI::AddedStructorArgCounts ExtraArgs = 21720b57cec5SDimitry Andric CGM.getCXXABI().addImplicitConstructorArgs(*this, D, Type, ForVirtualBase, 21730b57cec5SDimitry Andric Delegating, Args); 21740b57cec5SDimitry Andric 21750b57cec5SDimitry Andric // Emit the call. 21760b57cec5SDimitry Andric llvm::Constant *CalleePtr = CGM.getAddrOfCXXStructor(GlobalDecl(D, Type)); 21770b57cec5SDimitry Andric const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall( 21780b57cec5SDimitry Andric Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs); 21790b57cec5SDimitry Andric CGCallee Callee = CGCallee::forDirect(CalleePtr, GlobalDecl(D, Type)); 2180fe6060f1SDimitry Andric EmitCall(Info, Callee, ReturnValueSlot(), Args, nullptr, false, Loc); 21810b57cec5SDimitry Andric 21820b57cec5SDimitry Andric // Generate vtable assumptions if we're constructing a complete object 21830b57cec5SDimitry Andric // with a vtable. We don't do this for base subobjects for two reasons: 21840b57cec5SDimitry Andric // first, it's incorrect for classes with virtual bases, and second, we're 21850b57cec5SDimitry Andric // about to overwrite the vptrs anyway. 21860b57cec5SDimitry Andric // We also have to make sure if we can refer to vtable: 21870b57cec5SDimitry Andric // - Otherwise we can refer to vtable if it's safe to speculatively emit. 21880b57cec5SDimitry Andric // FIXME: If vtable is used by ctor/dtor, or if vtable is external and we are 21890b57cec5SDimitry Andric // sure that definition of vtable is not hidden, 21900b57cec5SDimitry Andric // then we are always safe to refer to it. 21910b57cec5SDimitry Andric // FIXME: It looks like InstCombine is very inefficient on dealing with 21920b57cec5SDimitry Andric // assumes. Make assumption loads require -fstrict-vtable-pointers temporarily. 21930b57cec5SDimitry Andric if (CGM.getCodeGenOpts().OptimizationLevel > 0 && 21940b57cec5SDimitry Andric ClassDecl->isDynamicClass() && Type != Ctor_Base && 21950b57cec5SDimitry Andric CGM.getCXXABI().canSpeculativelyEmitVTable(ClassDecl) && 21960b57cec5SDimitry Andric CGM.getCodeGenOpts().StrictVTablePointers) 21970b57cec5SDimitry Andric EmitVTableAssumptionLoads(ClassDecl, This); 21980b57cec5SDimitry Andric } 21990b57cec5SDimitry Andric 22000b57cec5SDimitry Andric void CodeGenFunction::EmitInheritedCXXConstructorCall( 22010b57cec5SDimitry Andric const CXXConstructorDecl *D, bool ForVirtualBase, Address This, 22020b57cec5SDimitry Andric bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E) { 22030b57cec5SDimitry Andric CallArgList Args; 22040b57cec5SDimitry Andric CallArg ThisArg(RValue::get(This.getPointer()), D->getThisType()); 22050b57cec5SDimitry Andric 22060b57cec5SDimitry Andric // Forward the parameters. 22070b57cec5SDimitry Andric if (InheritedFromVBase && 22080b57cec5SDimitry Andric CGM.getTarget().getCXXABI().hasConstructorVariants()) { 22090b57cec5SDimitry Andric // Nothing to do; this construction is not responsible for constructing 22100b57cec5SDimitry Andric // the base class containing the inherited constructor. 22110b57cec5SDimitry Andric // FIXME: Can we just pass undef's for the remaining arguments if we don't 22120b57cec5SDimitry Andric // have constructor variants? 22130b57cec5SDimitry Andric Args.push_back(ThisArg); 22140b57cec5SDimitry Andric } else if (!CXXInheritedCtorInitExprArgs.empty()) { 22150b57cec5SDimitry Andric // The inheriting constructor was inlined; just inject its arguments. 22160b57cec5SDimitry Andric assert(CXXInheritedCtorInitExprArgs.size() >= D->getNumParams() && 22170b57cec5SDimitry Andric "wrong number of parameters for inherited constructor call"); 22180b57cec5SDimitry Andric Args = CXXInheritedCtorInitExprArgs; 22190b57cec5SDimitry Andric Args[0] = ThisArg; 22200b57cec5SDimitry Andric } else { 22210b57cec5SDimitry Andric // The inheriting constructor was not inlined. Emit delegating arguments. 22220b57cec5SDimitry Andric Args.push_back(ThisArg); 22230b57cec5SDimitry Andric const auto *OuterCtor = cast<CXXConstructorDecl>(CurCodeDecl); 22240b57cec5SDimitry Andric assert(OuterCtor->getNumParams() == D->getNumParams()); 22250b57cec5SDimitry Andric assert(!OuterCtor->isVariadic() && "should have been inlined"); 22260b57cec5SDimitry Andric 22270b57cec5SDimitry Andric for (const auto *Param : OuterCtor->parameters()) { 22280b57cec5SDimitry Andric assert(getContext().hasSameUnqualifiedType( 22290b57cec5SDimitry Andric OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->getType(), 22300b57cec5SDimitry Andric Param->getType())); 22310b57cec5SDimitry Andric EmitDelegateCallArg(Args, Param, E->getLocation()); 22320b57cec5SDimitry Andric 22330b57cec5SDimitry Andric // Forward __attribute__(pass_object_size). 22340b57cec5SDimitry Andric if (Param->hasAttr<PassObjectSizeAttr>()) { 22350b57cec5SDimitry Andric auto *POSParam = SizeArguments[Param]; 22360b57cec5SDimitry Andric assert(POSParam && "missing pass_object_size value for forwarding"); 22370b57cec5SDimitry Andric EmitDelegateCallArg(Args, POSParam, E->getLocation()); 22380b57cec5SDimitry Andric } 22390b57cec5SDimitry Andric } 22400b57cec5SDimitry Andric } 22410b57cec5SDimitry Andric 22420b57cec5SDimitry Andric EmitCXXConstructorCall(D, Ctor_Base, ForVirtualBase, /*Delegating*/false, 22430b57cec5SDimitry Andric This, Args, AggValueSlot::MayOverlap, 22440b57cec5SDimitry Andric E->getLocation(), /*NewPointerIsChecked*/true); 22450b57cec5SDimitry Andric } 22460b57cec5SDimitry Andric 22470b57cec5SDimitry Andric void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall( 22480b57cec5SDimitry Andric const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase, 22490b57cec5SDimitry Andric bool Delegating, CallArgList &Args) { 22500b57cec5SDimitry Andric GlobalDecl GD(Ctor, CtorType); 22510b57cec5SDimitry Andric InlinedInheritingConstructorScope Scope(*this, GD); 22520b57cec5SDimitry Andric ApplyInlineDebugLocation DebugScope(*this, GD); 22530b57cec5SDimitry Andric RunCleanupsScope RunCleanups(*this); 22540b57cec5SDimitry Andric 22550b57cec5SDimitry Andric // Save the arguments to be passed to the inherited constructor. 22560b57cec5SDimitry Andric CXXInheritedCtorInitExprArgs = Args; 22570b57cec5SDimitry Andric 22580b57cec5SDimitry Andric FunctionArgList Params; 22590b57cec5SDimitry Andric QualType RetType = BuildFunctionArgList(CurGD, Params); 22600b57cec5SDimitry Andric FnRetTy = RetType; 22610b57cec5SDimitry Andric 22620b57cec5SDimitry Andric // Insert any ABI-specific implicit constructor arguments. 22630b57cec5SDimitry Andric CGM.getCXXABI().addImplicitConstructorArgs(*this, Ctor, CtorType, 22640b57cec5SDimitry Andric ForVirtualBase, Delegating, Args); 22650b57cec5SDimitry Andric 22660b57cec5SDimitry Andric // Emit a simplified prolog. We only need to emit the implicit params. 22670b57cec5SDimitry Andric assert(Args.size() >= Params.size() && "too few arguments for call"); 22680b57cec5SDimitry Andric for (unsigned I = 0, N = Args.size(); I != N; ++I) { 22690b57cec5SDimitry Andric if (I < Params.size() && isa<ImplicitParamDecl>(Params[I])) { 22700b57cec5SDimitry Andric const RValue &RV = Args[I].getRValue(*this); 22710b57cec5SDimitry Andric assert(!RV.isComplex() && "complex indirect params not supported"); 22720b57cec5SDimitry Andric ParamValue Val = RV.isScalar() 22730b57cec5SDimitry Andric ? ParamValue::forDirect(RV.getScalarVal()) 22740b57cec5SDimitry Andric : ParamValue::forIndirect(RV.getAggregateAddress()); 22750b57cec5SDimitry Andric EmitParmDecl(*Params[I], Val, I + 1); 22760b57cec5SDimitry Andric } 22770b57cec5SDimitry Andric } 22780b57cec5SDimitry Andric 22790b57cec5SDimitry Andric // Create a return value slot if the ABI implementation wants one. 22800b57cec5SDimitry Andric // FIXME: This is dumb, we should ask the ABI not to try to set the return 22810b57cec5SDimitry Andric // value instead. 22820b57cec5SDimitry Andric if (!RetType->isVoidType()) 22830b57cec5SDimitry Andric ReturnValue = CreateIRTemp(RetType, "retval.inhctor"); 22840b57cec5SDimitry Andric 22850b57cec5SDimitry Andric CGM.getCXXABI().EmitInstanceFunctionProlog(*this); 22860b57cec5SDimitry Andric CXXThisValue = CXXABIThisValue; 22870b57cec5SDimitry Andric 22880b57cec5SDimitry Andric // Directly emit the constructor initializers. 22890b57cec5SDimitry Andric EmitCtorPrologue(Ctor, CtorType, Params); 22900b57cec5SDimitry Andric } 22910b57cec5SDimitry Andric 22920b57cec5SDimitry Andric void CodeGenFunction::EmitVTableAssumptionLoad(const VPtr &Vptr, Address This) { 22930b57cec5SDimitry Andric llvm::Value *VTableGlobal = 22940b57cec5SDimitry Andric CGM.getCXXABI().getVTableAddressPoint(Vptr.Base, Vptr.VTableClass); 22950b57cec5SDimitry Andric if (!VTableGlobal) 22960b57cec5SDimitry Andric return; 22970b57cec5SDimitry Andric 22980b57cec5SDimitry Andric // We can just use the base offset in the complete class. 22990b57cec5SDimitry Andric CharUnits NonVirtualOffset = Vptr.Base.getBaseOffset(); 23000b57cec5SDimitry Andric 23010b57cec5SDimitry Andric if (!NonVirtualOffset.isZero()) 23020b57cec5SDimitry Andric This = 23030b57cec5SDimitry Andric ApplyNonVirtualAndVirtualOffset(*this, This, NonVirtualOffset, nullptr, 23040b57cec5SDimitry Andric Vptr.VTableClass, Vptr.NearestVBase); 23050b57cec5SDimitry Andric 23060b57cec5SDimitry Andric llvm::Value *VPtrValue = 23070b57cec5SDimitry Andric GetVTablePtr(This, VTableGlobal->getType(), Vptr.VTableClass); 23080b57cec5SDimitry Andric llvm::Value *Cmp = 23090b57cec5SDimitry Andric Builder.CreateICmpEQ(VPtrValue, VTableGlobal, "cmp.vtables"); 23100b57cec5SDimitry Andric Builder.CreateAssumption(Cmp); 23110b57cec5SDimitry Andric } 23120b57cec5SDimitry Andric 23130b57cec5SDimitry Andric void CodeGenFunction::EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, 23140b57cec5SDimitry Andric Address This) { 23150b57cec5SDimitry Andric if (CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl)) 23160b57cec5SDimitry Andric for (const VPtr &Vptr : getVTablePointers(ClassDecl)) 23170b57cec5SDimitry Andric EmitVTableAssumptionLoad(Vptr, This); 23180b57cec5SDimitry Andric } 23190b57cec5SDimitry Andric 23200b57cec5SDimitry Andric void 23210b57cec5SDimitry Andric CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, 23220b57cec5SDimitry Andric Address This, Address Src, 23230b57cec5SDimitry Andric const CXXConstructExpr *E) { 23240b57cec5SDimitry Andric const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>(); 23250b57cec5SDimitry Andric 23260b57cec5SDimitry Andric CallArgList Args; 23270b57cec5SDimitry Andric 23280b57cec5SDimitry Andric // Push the this ptr. 23290b57cec5SDimitry Andric Args.add(RValue::get(This.getPointer()), D->getThisType()); 23300b57cec5SDimitry Andric 23310b57cec5SDimitry Andric // Push the src ptr. 23320b57cec5SDimitry Andric QualType QT = *(FPT->param_type_begin()); 23330b57cec5SDimitry Andric llvm::Type *t = CGM.getTypes().ConvertType(QT); 23340b57cec5SDimitry Andric Src = Builder.CreateBitCast(Src, t); 23350b57cec5SDimitry Andric Args.add(RValue::get(Src.getPointer()), QT); 23360b57cec5SDimitry Andric 23370b57cec5SDimitry Andric // Skip over first argument (Src). 23380b57cec5SDimitry Andric EmitCallArgs(Args, FPT, drop_begin(E->arguments(), 1), E->getConstructor(), 23390b57cec5SDimitry Andric /*ParamsToSkip*/ 1); 23400b57cec5SDimitry Andric 23410b57cec5SDimitry Andric EmitCXXConstructorCall(D, Ctor_Complete, /*ForVirtualBase*/false, 23420b57cec5SDimitry Andric /*Delegating*/false, This, Args, 23430b57cec5SDimitry Andric AggValueSlot::MayOverlap, E->getExprLoc(), 23440b57cec5SDimitry Andric /*NewPointerIsChecked*/false); 23450b57cec5SDimitry Andric } 23460b57cec5SDimitry Andric 23470b57cec5SDimitry Andric void 23480b57cec5SDimitry Andric CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, 23490b57cec5SDimitry Andric CXXCtorType CtorType, 23500b57cec5SDimitry Andric const FunctionArgList &Args, 23510b57cec5SDimitry Andric SourceLocation Loc) { 23520b57cec5SDimitry Andric CallArgList DelegateArgs; 23530b57cec5SDimitry Andric 23540b57cec5SDimitry Andric FunctionArgList::const_iterator I = Args.begin(), E = Args.end(); 23550b57cec5SDimitry Andric assert(I != E && "no parameters to constructor"); 23560b57cec5SDimitry Andric 23570b57cec5SDimitry Andric // this 23580b57cec5SDimitry Andric Address This = LoadCXXThisAddress(); 23590b57cec5SDimitry Andric DelegateArgs.add(RValue::get(This.getPointer()), (*I)->getType()); 23600b57cec5SDimitry Andric ++I; 23610b57cec5SDimitry Andric 23620b57cec5SDimitry Andric // FIXME: The location of the VTT parameter in the parameter list is 23630b57cec5SDimitry Andric // specific to the Itanium ABI and shouldn't be hardcoded here. 23640b57cec5SDimitry Andric if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) { 23650b57cec5SDimitry Andric assert(I != E && "cannot skip vtt parameter, already done with args"); 23660b57cec5SDimitry Andric assert((*I)->getType()->isPointerType() && 23670b57cec5SDimitry Andric "skipping parameter not of vtt type"); 23680b57cec5SDimitry Andric ++I; 23690b57cec5SDimitry Andric } 23700b57cec5SDimitry Andric 23710b57cec5SDimitry Andric // Explicit arguments. 23720b57cec5SDimitry Andric for (; I != E; ++I) { 23730b57cec5SDimitry Andric const VarDecl *param = *I; 23740b57cec5SDimitry Andric // FIXME: per-argument source location 23750b57cec5SDimitry Andric EmitDelegateCallArg(DelegateArgs, param, Loc); 23760b57cec5SDimitry Andric } 23770b57cec5SDimitry Andric 23780b57cec5SDimitry Andric EmitCXXConstructorCall(Ctor, CtorType, /*ForVirtualBase=*/false, 23790b57cec5SDimitry Andric /*Delegating=*/true, This, DelegateArgs, 23800b57cec5SDimitry Andric AggValueSlot::MayOverlap, Loc, 23810b57cec5SDimitry Andric /*NewPointerIsChecked=*/true); 23820b57cec5SDimitry Andric } 23830b57cec5SDimitry Andric 23840b57cec5SDimitry Andric namespace { 23850b57cec5SDimitry Andric struct CallDelegatingCtorDtor final : EHScopeStack::Cleanup { 23860b57cec5SDimitry Andric const CXXDestructorDecl *Dtor; 23870b57cec5SDimitry Andric Address Addr; 23880b57cec5SDimitry Andric CXXDtorType Type; 23890b57cec5SDimitry Andric 23900b57cec5SDimitry Andric CallDelegatingCtorDtor(const CXXDestructorDecl *D, Address Addr, 23910b57cec5SDimitry Andric CXXDtorType Type) 23920b57cec5SDimitry Andric : Dtor(D), Addr(Addr), Type(Type) {} 23930b57cec5SDimitry Andric 23940b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 23950b57cec5SDimitry Andric // We are calling the destructor from within the constructor. 23960b57cec5SDimitry Andric // Therefore, "this" should have the expected type. 23970b57cec5SDimitry Andric QualType ThisTy = Dtor->getThisObjectType(); 23980b57cec5SDimitry Andric CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false, 23990b57cec5SDimitry Andric /*Delegating=*/true, Addr, ThisTy); 24000b57cec5SDimitry Andric } 24010b57cec5SDimitry Andric }; 24020b57cec5SDimitry Andric } // end anonymous namespace 24030b57cec5SDimitry Andric 24040b57cec5SDimitry Andric void 24050b57cec5SDimitry Andric CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, 24060b57cec5SDimitry Andric const FunctionArgList &Args) { 24070b57cec5SDimitry Andric assert(Ctor->isDelegatingConstructor()); 24080b57cec5SDimitry Andric 24090b57cec5SDimitry Andric Address ThisPtr = LoadCXXThisAddress(); 24100b57cec5SDimitry Andric 24110b57cec5SDimitry Andric AggValueSlot AggSlot = 24120b57cec5SDimitry Andric AggValueSlot::forAddr(ThisPtr, Qualifiers(), 24130b57cec5SDimitry Andric AggValueSlot::IsDestructed, 24140b57cec5SDimitry Andric AggValueSlot::DoesNotNeedGCBarriers, 24150b57cec5SDimitry Andric AggValueSlot::IsNotAliased, 24160b57cec5SDimitry Andric AggValueSlot::MayOverlap, 24170b57cec5SDimitry Andric AggValueSlot::IsNotZeroed, 24180b57cec5SDimitry Andric // Checks are made by the code that calls constructor. 24190b57cec5SDimitry Andric AggValueSlot::IsSanitizerChecked); 24200b57cec5SDimitry Andric 24210b57cec5SDimitry Andric EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); 24220b57cec5SDimitry Andric 24230b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = Ctor->getParent(); 24240b57cec5SDimitry Andric if (CGM.getLangOpts().Exceptions && !ClassDecl->hasTrivialDestructor()) { 24250b57cec5SDimitry Andric CXXDtorType Type = 24260b57cec5SDimitry Andric CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base; 24270b57cec5SDimitry Andric 24280b57cec5SDimitry Andric EHStack.pushCleanup<CallDelegatingCtorDtor>(EHCleanup, 24290b57cec5SDimitry Andric ClassDecl->getDestructor(), 24300b57cec5SDimitry Andric ThisPtr, Type); 24310b57cec5SDimitry Andric } 24320b57cec5SDimitry Andric } 24330b57cec5SDimitry Andric 24340b57cec5SDimitry Andric void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, 24350b57cec5SDimitry Andric CXXDtorType Type, 24360b57cec5SDimitry Andric bool ForVirtualBase, 24370b57cec5SDimitry Andric bool Delegating, Address This, 24380b57cec5SDimitry Andric QualType ThisTy) { 24390b57cec5SDimitry Andric CGM.getCXXABI().EmitDestructorCall(*this, DD, Type, ForVirtualBase, 24400b57cec5SDimitry Andric Delegating, This, ThisTy); 24410b57cec5SDimitry Andric } 24420b57cec5SDimitry Andric 24430b57cec5SDimitry Andric namespace { 24440b57cec5SDimitry Andric struct CallLocalDtor final : EHScopeStack::Cleanup { 24450b57cec5SDimitry Andric const CXXDestructorDecl *Dtor; 24460b57cec5SDimitry Andric Address Addr; 24470b57cec5SDimitry Andric QualType Ty; 24480b57cec5SDimitry Andric 24490b57cec5SDimitry Andric CallLocalDtor(const CXXDestructorDecl *D, Address Addr, QualType Ty) 24500b57cec5SDimitry Andric : Dtor(D), Addr(Addr), Ty(Ty) {} 24510b57cec5SDimitry Andric 24520b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 24530b57cec5SDimitry Andric CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, 24540b57cec5SDimitry Andric /*ForVirtualBase=*/false, 24550b57cec5SDimitry Andric /*Delegating=*/false, Addr, Ty); 24560b57cec5SDimitry Andric } 24570b57cec5SDimitry Andric }; 24580b57cec5SDimitry Andric } // end anonymous namespace 24590b57cec5SDimitry Andric 24600b57cec5SDimitry Andric void CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D, 24610b57cec5SDimitry Andric QualType T, Address Addr) { 24620b57cec5SDimitry Andric EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr, T); 24630b57cec5SDimitry Andric } 24640b57cec5SDimitry Andric 24650b57cec5SDimitry Andric void CodeGenFunction::PushDestructorCleanup(QualType T, Address Addr) { 24660b57cec5SDimitry Andric CXXRecordDecl *ClassDecl = T->getAsCXXRecordDecl(); 24670b57cec5SDimitry Andric if (!ClassDecl) return; 24680b57cec5SDimitry Andric if (ClassDecl->hasTrivialDestructor()) return; 24690b57cec5SDimitry Andric 24700b57cec5SDimitry Andric const CXXDestructorDecl *D = ClassDecl->getDestructor(); 24710b57cec5SDimitry Andric assert(D && D->isUsed() && "destructor not marked as used!"); 24720b57cec5SDimitry Andric PushDestructorCleanup(D, T, Addr); 24730b57cec5SDimitry Andric } 24740b57cec5SDimitry Andric 24750b57cec5SDimitry Andric void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) { 24760b57cec5SDimitry Andric // Compute the address point. 24770b57cec5SDimitry Andric llvm::Value *VTableAddressPoint = 24780b57cec5SDimitry Andric CGM.getCXXABI().getVTableAddressPointInStructor( 24790b57cec5SDimitry Andric *this, Vptr.VTableClass, Vptr.Base, Vptr.NearestVBase); 24800b57cec5SDimitry Andric 24810b57cec5SDimitry Andric if (!VTableAddressPoint) 24820b57cec5SDimitry Andric return; 24830b57cec5SDimitry Andric 24840b57cec5SDimitry Andric // Compute where to store the address point. 24850b57cec5SDimitry Andric llvm::Value *VirtualOffset = nullptr; 24860b57cec5SDimitry Andric CharUnits NonVirtualOffset = CharUnits::Zero(); 24870b57cec5SDimitry Andric 24880b57cec5SDimitry Andric if (CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*this, Vptr)) { 24890b57cec5SDimitry Andric // We need to use the virtual base offset offset because the virtual base 24900b57cec5SDimitry Andric // might have a different offset in the most derived class. 24910b57cec5SDimitry Andric 24920b57cec5SDimitry Andric VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset( 24930b57cec5SDimitry Andric *this, LoadCXXThisAddress(), Vptr.VTableClass, Vptr.NearestVBase); 24940b57cec5SDimitry Andric NonVirtualOffset = Vptr.OffsetFromNearestVBase; 24950b57cec5SDimitry Andric } else { 24960b57cec5SDimitry Andric // We can just use the base offset in the complete class. 24970b57cec5SDimitry Andric NonVirtualOffset = Vptr.Base.getBaseOffset(); 24980b57cec5SDimitry Andric } 24990b57cec5SDimitry Andric 25000b57cec5SDimitry Andric // Apply the offsets. 25010b57cec5SDimitry Andric Address VTableField = LoadCXXThisAddress(); 25020b57cec5SDimitry Andric if (!NonVirtualOffset.isZero() || VirtualOffset) 25030b57cec5SDimitry Andric VTableField = ApplyNonVirtualAndVirtualOffset( 25040b57cec5SDimitry Andric *this, VTableField, NonVirtualOffset, VirtualOffset, Vptr.VTableClass, 25050b57cec5SDimitry Andric Vptr.NearestVBase); 25060b57cec5SDimitry Andric 25070b57cec5SDimitry Andric // Finally, store the address point. Use the same LLVM types as the field to 25080b57cec5SDimitry Andric // support optimization. 2509e8d8bef9SDimitry Andric unsigned GlobalsAS = CGM.getDataLayout().getDefaultGlobalsAddressSpace(); 2510e8d8bef9SDimitry Andric unsigned ProgAS = CGM.getDataLayout().getProgramAddressSpace(); 25110b57cec5SDimitry Andric llvm::Type *VTablePtrTy = 25120b57cec5SDimitry Andric llvm::FunctionType::get(CGM.Int32Ty, /*isVarArg=*/true) 2513e8d8bef9SDimitry Andric ->getPointerTo(ProgAS) 2514e8d8bef9SDimitry Andric ->getPointerTo(GlobalsAS); 2515349cc55cSDimitry Andric // vtable field is is derived from `this` pointer, therefore they should be in 2516349cc55cSDimitry Andric // the same addr space. Note that this might not be LLVM address space 0. 25170eae32dcSDimitry Andric VTableField = Builder.CreateElementBitCast(VTableField, VTablePtrTy); 2518349cc55cSDimitry Andric VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy); 25190b57cec5SDimitry Andric 25200b57cec5SDimitry Andric llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField); 25210b57cec5SDimitry Andric TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTablePtrTy); 25220b57cec5SDimitry Andric CGM.DecorateInstructionWithTBAA(Store, TBAAInfo); 25230b57cec5SDimitry Andric if (CGM.getCodeGenOpts().OptimizationLevel > 0 && 25240b57cec5SDimitry Andric CGM.getCodeGenOpts().StrictVTablePointers) 25250b57cec5SDimitry Andric CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.VTableClass); 25260b57cec5SDimitry Andric } 25270b57cec5SDimitry Andric 25280b57cec5SDimitry Andric CodeGenFunction::VPtrsVector 25290b57cec5SDimitry Andric CodeGenFunction::getVTablePointers(const CXXRecordDecl *VTableClass) { 25300b57cec5SDimitry Andric CodeGenFunction::VPtrsVector VPtrsResult; 25310b57cec5SDimitry Andric VisitedVirtualBasesSetTy VBases; 25320b57cec5SDimitry Andric getVTablePointers(BaseSubobject(VTableClass, CharUnits::Zero()), 25330b57cec5SDimitry Andric /*NearestVBase=*/nullptr, 25340b57cec5SDimitry Andric /*OffsetFromNearestVBase=*/CharUnits::Zero(), 25350b57cec5SDimitry Andric /*BaseIsNonVirtualPrimaryBase=*/false, VTableClass, VBases, 25360b57cec5SDimitry Andric VPtrsResult); 25370b57cec5SDimitry Andric return VPtrsResult; 25380b57cec5SDimitry Andric } 25390b57cec5SDimitry Andric 25400b57cec5SDimitry Andric void CodeGenFunction::getVTablePointers(BaseSubobject Base, 25410b57cec5SDimitry Andric const CXXRecordDecl *NearestVBase, 25420b57cec5SDimitry Andric CharUnits OffsetFromNearestVBase, 25430b57cec5SDimitry Andric bool BaseIsNonVirtualPrimaryBase, 25440b57cec5SDimitry Andric const CXXRecordDecl *VTableClass, 25450b57cec5SDimitry Andric VisitedVirtualBasesSetTy &VBases, 25460b57cec5SDimitry Andric VPtrsVector &Vptrs) { 25470b57cec5SDimitry Andric // If this base is a non-virtual primary base the address point has already 25480b57cec5SDimitry Andric // been set. 25490b57cec5SDimitry Andric if (!BaseIsNonVirtualPrimaryBase) { 25500b57cec5SDimitry Andric // Initialize the vtable pointer for this base. 25510b57cec5SDimitry Andric VPtr Vptr = {Base, NearestVBase, OffsetFromNearestVBase, VTableClass}; 25520b57cec5SDimitry Andric Vptrs.push_back(Vptr); 25530b57cec5SDimitry Andric } 25540b57cec5SDimitry Andric 25550b57cec5SDimitry Andric const CXXRecordDecl *RD = Base.getBase(); 25560b57cec5SDimitry Andric 25570b57cec5SDimitry Andric // Traverse bases. 25580b57cec5SDimitry Andric for (const auto &I : RD->bases()) { 2559a7dea167SDimitry Andric auto *BaseDecl = 2560a7dea167SDimitry Andric cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 25610b57cec5SDimitry Andric 25620b57cec5SDimitry Andric // Ignore classes without a vtable. 25630b57cec5SDimitry Andric if (!BaseDecl->isDynamicClass()) 25640b57cec5SDimitry Andric continue; 25650b57cec5SDimitry Andric 25660b57cec5SDimitry Andric CharUnits BaseOffset; 25670b57cec5SDimitry Andric CharUnits BaseOffsetFromNearestVBase; 25680b57cec5SDimitry Andric bool BaseDeclIsNonVirtualPrimaryBase; 25690b57cec5SDimitry Andric 25700b57cec5SDimitry Andric if (I.isVirtual()) { 25710b57cec5SDimitry Andric // Check if we've visited this virtual base before. 25720b57cec5SDimitry Andric if (!VBases.insert(BaseDecl).second) 25730b57cec5SDimitry Andric continue; 25740b57cec5SDimitry Andric 25750b57cec5SDimitry Andric const ASTRecordLayout &Layout = 25760b57cec5SDimitry Andric getContext().getASTRecordLayout(VTableClass); 25770b57cec5SDimitry Andric 25780b57cec5SDimitry Andric BaseOffset = Layout.getVBaseClassOffset(BaseDecl); 25790b57cec5SDimitry Andric BaseOffsetFromNearestVBase = CharUnits::Zero(); 25800b57cec5SDimitry Andric BaseDeclIsNonVirtualPrimaryBase = false; 25810b57cec5SDimitry Andric } else { 25820b57cec5SDimitry Andric const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 25830b57cec5SDimitry Andric 25840b57cec5SDimitry Andric BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl); 25850b57cec5SDimitry Andric BaseOffsetFromNearestVBase = 25860b57cec5SDimitry Andric OffsetFromNearestVBase + Layout.getBaseClassOffset(BaseDecl); 25870b57cec5SDimitry Andric BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl; 25880b57cec5SDimitry Andric } 25890b57cec5SDimitry Andric 25900b57cec5SDimitry Andric getVTablePointers( 25910b57cec5SDimitry Andric BaseSubobject(BaseDecl, BaseOffset), 25920b57cec5SDimitry Andric I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase, 25930b57cec5SDimitry Andric BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs); 25940b57cec5SDimitry Andric } 25950b57cec5SDimitry Andric } 25960b57cec5SDimitry Andric 25970b57cec5SDimitry Andric void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { 25980b57cec5SDimitry Andric // Ignore classes without a vtable. 25990b57cec5SDimitry Andric if (!RD->isDynamicClass()) 26000b57cec5SDimitry Andric return; 26010b57cec5SDimitry Andric 26020b57cec5SDimitry Andric // Initialize the vtable pointers for this class and all of its bases. 26030b57cec5SDimitry Andric if (CGM.getCXXABI().doStructorsInitializeVPtrs(RD)) 26040b57cec5SDimitry Andric for (const VPtr &Vptr : getVTablePointers(RD)) 26050b57cec5SDimitry Andric InitializeVTablePointer(Vptr); 26060b57cec5SDimitry Andric 26070b57cec5SDimitry Andric if (RD->getNumVBases()) 26080b57cec5SDimitry Andric CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, RD); 26090b57cec5SDimitry Andric } 26100b57cec5SDimitry Andric 26110b57cec5SDimitry Andric llvm::Value *CodeGenFunction::GetVTablePtr(Address This, 26120b57cec5SDimitry Andric llvm::Type *VTableTy, 26130b57cec5SDimitry Andric const CXXRecordDecl *RD) { 26140b57cec5SDimitry Andric Address VTablePtrSrc = Builder.CreateElementBitCast(This, VTableTy); 26150b57cec5SDimitry Andric llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); 26160b57cec5SDimitry Andric TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy); 26170b57cec5SDimitry Andric CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo); 26180b57cec5SDimitry Andric 26190b57cec5SDimitry Andric if (CGM.getCodeGenOpts().OptimizationLevel > 0 && 26200b57cec5SDimitry Andric CGM.getCodeGenOpts().StrictVTablePointers) 26210b57cec5SDimitry Andric CGM.DecorateInstructionWithInvariantGroup(VTable, RD); 26220b57cec5SDimitry Andric 26230b57cec5SDimitry Andric return VTable; 26240b57cec5SDimitry Andric } 26250b57cec5SDimitry Andric 26260b57cec5SDimitry Andric // If a class has a single non-virtual base and does not introduce or override 26270b57cec5SDimitry Andric // virtual member functions or fields, it will have the same layout as its base. 26280b57cec5SDimitry Andric // This function returns the least derived such class. 26290b57cec5SDimitry Andric // 26300b57cec5SDimitry Andric // Casting an instance of a base class to such a derived class is technically 26310b57cec5SDimitry Andric // undefined behavior, but it is a relatively common hack for introducing member 26320b57cec5SDimitry Andric // functions on class instances with specific properties (e.g. llvm::Operator) 26330b57cec5SDimitry Andric // that works under most compilers and should not have security implications, so 26340b57cec5SDimitry Andric // we allow it by default. It can be disabled with -fsanitize=cfi-cast-strict. 26350b57cec5SDimitry Andric static const CXXRecordDecl * 26360b57cec5SDimitry Andric LeastDerivedClassWithSameLayout(const CXXRecordDecl *RD) { 26370b57cec5SDimitry Andric if (!RD->field_empty()) 26380b57cec5SDimitry Andric return RD; 26390b57cec5SDimitry Andric 26400b57cec5SDimitry Andric if (RD->getNumVBases() != 0) 26410b57cec5SDimitry Andric return RD; 26420b57cec5SDimitry Andric 26430b57cec5SDimitry Andric if (RD->getNumBases() != 1) 26440b57cec5SDimitry Andric return RD; 26450b57cec5SDimitry Andric 26460b57cec5SDimitry Andric for (const CXXMethodDecl *MD : RD->methods()) { 26470b57cec5SDimitry Andric if (MD->isVirtual()) { 26480b57cec5SDimitry Andric // Virtual member functions are only ok if they are implicit destructors 26490b57cec5SDimitry Andric // because the implicit destructor will have the same semantics as the 26500b57cec5SDimitry Andric // base class's destructor if no fields are added. 26510b57cec5SDimitry Andric if (isa<CXXDestructorDecl>(MD) && MD->isImplicit()) 26520b57cec5SDimitry Andric continue; 26530b57cec5SDimitry Andric return RD; 26540b57cec5SDimitry Andric } 26550b57cec5SDimitry Andric } 26560b57cec5SDimitry Andric 26570b57cec5SDimitry Andric return LeastDerivedClassWithSameLayout( 26580b57cec5SDimitry Andric RD->bases_begin()->getType()->getAsCXXRecordDecl()); 26590b57cec5SDimitry Andric } 26600b57cec5SDimitry Andric 26610b57cec5SDimitry Andric void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, 26620b57cec5SDimitry Andric llvm::Value *VTable, 26630b57cec5SDimitry Andric SourceLocation Loc) { 26640b57cec5SDimitry Andric if (SanOpts.has(SanitizerKind::CFIVCall)) 26650b57cec5SDimitry Andric EmitVTablePtrCheckForCall(RD, VTable, CodeGenFunction::CFITCK_VCall, Loc); 26660b57cec5SDimitry Andric else if (CGM.getCodeGenOpts().WholeProgramVTables && 26675ffd83dbSDimitry Andric // Don't insert type test assumes if we are forcing public std 26685ffd83dbSDimitry Andric // visibility. 26695ffd83dbSDimitry Andric !CGM.HasLTOVisibilityPublicStd(RD)) { 26700b57cec5SDimitry Andric llvm::Metadata *MD = 26710b57cec5SDimitry Andric CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)); 26720b57cec5SDimitry Andric llvm::Value *TypeId = 26730b57cec5SDimitry Andric llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD); 26740b57cec5SDimitry Andric 26750b57cec5SDimitry Andric llvm::Value *CastedVTable = Builder.CreateBitCast(VTable, Int8PtrTy); 26760b57cec5SDimitry Andric llvm::Value *TypeTest = 26770b57cec5SDimitry Andric Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test), 26780b57cec5SDimitry Andric {CastedVTable, TypeId}); 26790b57cec5SDimitry Andric Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest); 26800b57cec5SDimitry Andric } 26810b57cec5SDimitry Andric } 26820b57cec5SDimitry Andric 26830b57cec5SDimitry Andric void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, 26840b57cec5SDimitry Andric llvm::Value *VTable, 26850b57cec5SDimitry Andric CFITypeCheckKind TCK, 26860b57cec5SDimitry Andric SourceLocation Loc) { 26870b57cec5SDimitry Andric if (!SanOpts.has(SanitizerKind::CFICastStrict)) 26880b57cec5SDimitry Andric RD = LeastDerivedClassWithSameLayout(RD); 26890b57cec5SDimitry Andric 26900b57cec5SDimitry Andric EmitVTablePtrCheck(RD, VTable, TCK, Loc); 26910b57cec5SDimitry Andric } 26920b57cec5SDimitry Andric 26930b57cec5SDimitry Andric void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, 26940b57cec5SDimitry Andric llvm::Value *Derived, 26950b57cec5SDimitry Andric bool MayBeNull, 26960b57cec5SDimitry Andric CFITypeCheckKind TCK, 26970b57cec5SDimitry Andric SourceLocation Loc) { 26980b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) 26990b57cec5SDimitry Andric return; 27000b57cec5SDimitry Andric 27010b57cec5SDimitry Andric auto *ClassTy = T->getAs<RecordType>(); 27020b57cec5SDimitry Andric if (!ClassTy) 27030b57cec5SDimitry Andric return; 27040b57cec5SDimitry Andric 27050b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassTy->getDecl()); 27060b57cec5SDimitry Andric 27070b57cec5SDimitry Andric if (!ClassDecl->isCompleteDefinition() || !ClassDecl->isDynamicClass()) 27080b57cec5SDimitry Andric return; 27090b57cec5SDimitry Andric 27100b57cec5SDimitry Andric if (!SanOpts.has(SanitizerKind::CFICastStrict)) 27110b57cec5SDimitry Andric ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl); 27120b57cec5SDimitry Andric 27130b57cec5SDimitry Andric llvm::BasicBlock *ContBlock = nullptr; 27140b57cec5SDimitry Andric 27150b57cec5SDimitry Andric if (MayBeNull) { 27160b57cec5SDimitry Andric llvm::Value *DerivedNotNull = 27170b57cec5SDimitry Andric Builder.CreateIsNotNull(Derived, "cast.nonnull"); 27180b57cec5SDimitry Andric 27190b57cec5SDimitry Andric llvm::BasicBlock *CheckBlock = createBasicBlock("cast.check"); 27200b57cec5SDimitry Andric ContBlock = createBasicBlock("cast.cont"); 27210b57cec5SDimitry Andric 27220b57cec5SDimitry Andric Builder.CreateCondBr(DerivedNotNull, CheckBlock, ContBlock); 27230b57cec5SDimitry Andric 27240b57cec5SDimitry Andric EmitBlock(CheckBlock); 27250b57cec5SDimitry Andric } 27260b57cec5SDimitry Andric 27270b57cec5SDimitry Andric llvm::Value *VTable; 27280b57cec5SDimitry Andric std::tie(VTable, ClassDecl) = CGM.getCXXABI().LoadVTablePtr( 27290b57cec5SDimitry Andric *this, Address(Derived, getPointerAlign()), ClassDecl); 27300b57cec5SDimitry Andric 27310b57cec5SDimitry Andric EmitVTablePtrCheck(ClassDecl, VTable, TCK, Loc); 27320b57cec5SDimitry Andric 27330b57cec5SDimitry Andric if (MayBeNull) { 27340b57cec5SDimitry Andric Builder.CreateBr(ContBlock); 27350b57cec5SDimitry Andric EmitBlock(ContBlock); 27360b57cec5SDimitry Andric } 27370b57cec5SDimitry Andric } 27380b57cec5SDimitry Andric 27390b57cec5SDimitry Andric void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD, 27400b57cec5SDimitry Andric llvm::Value *VTable, 27410b57cec5SDimitry Andric CFITypeCheckKind TCK, 27420b57cec5SDimitry Andric SourceLocation Loc) { 27430b57cec5SDimitry Andric if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso && 27440b57cec5SDimitry Andric !CGM.HasHiddenLTOVisibility(RD)) 27450b57cec5SDimitry Andric return; 27460b57cec5SDimitry Andric 27470b57cec5SDimitry Andric SanitizerMask M; 27480b57cec5SDimitry Andric llvm::SanitizerStatKind SSK; 27490b57cec5SDimitry Andric switch (TCK) { 27500b57cec5SDimitry Andric case CFITCK_VCall: 27510b57cec5SDimitry Andric M = SanitizerKind::CFIVCall; 27520b57cec5SDimitry Andric SSK = llvm::SanStat_CFI_VCall; 27530b57cec5SDimitry Andric break; 27540b57cec5SDimitry Andric case CFITCK_NVCall: 27550b57cec5SDimitry Andric M = SanitizerKind::CFINVCall; 27560b57cec5SDimitry Andric SSK = llvm::SanStat_CFI_NVCall; 27570b57cec5SDimitry Andric break; 27580b57cec5SDimitry Andric case CFITCK_DerivedCast: 27590b57cec5SDimitry Andric M = SanitizerKind::CFIDerivedCast; 27600b57cec5SDimitry Andric SSK = llvm::SanStat_CFI_DerivedCast; 27610b57cec5SDimitry Andric break; 27620b57cec5SDimitry Andric case CFITCK_UnrelatedCast: 27630b57cec5SDimitry Andric M = SanitizerKind::CFIUnrelatedCast; 27640b57cec5SDimitry Andric SSK = llvm::SanStat_CFI_UnrelatedCast; 27650b57cec5SDimitry Andric break; 27660b57cec5SDimitry Andric case CFITCK_ICall: 27670b57cec5SDimitry Andric case CFITCK_NVMFCall: 27680b57cec5SDimitry Andric case CFITCK_VMFCall: 27690b57cec5SDimitry Andric llvm_unreachable("unexpected sanitizer kind"); 27700b57cec5SDimitry Andric } 27710b57cec5SDimitry Andric 27720b57cec5SDimitry Andric std::string TypeName = RD->getQualifiedNameAsString(); 2773fe6060f1SDimitry Andric if (getContext().getNoSanitizeList().containsType(M, TypeName)) 27740b57cec5SDimitry Andric return; 27750b57cec5SDimitry Andric 27760b57cec5SDimitry Andric SanitizerScope SanScope(this); 27770b57cec5SDimitry Andric EmitSanitizerStatReport(SSK); 27780b57cec5SDimitry Andric 27790b57cec5SDimitry Andric llvm::Metadata *MD = 27800b57cec5SDimitry Andric CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)); 27810b57cec5SDimitry Andric llvm::Value *TypeId = llvm::MetadataAsValue::get(getLLVMContext(), MD); 27820b57cec5SDimitry Andric 27830b57cec5SDimitry Andric llvm::Value *CastedVTable = Builder.CreateBitCast(VTable, Int8PtrTy); 27840b57cec5SDimitry Andric llvm::Value *TypeTest = Builder.CreateCall( 27850b57cec5SDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, TypeId}); 27860b57cec5SDimitry Andric 27870b57cec5SDimitry Andric llvm::Constant *StaticData[] = { 27880b57cec5SDimitry Andric llvm::ConstantInt::get(Int8Ty, TCK), 27890b57cec5SDimitry Andric EmitCheckSourceLocation(Loc), 27900b57cec5SDimitry Andric EmitCheckTypeDescriptor(QualType(RD->getTypeForDecl(), 0)), 27910b57cec5SDimitry Andric }; 27920b57cec5SDimitry Andric 27930b57cec5SDimitry Andric auto CrossDsoTypeId = CGM.CreateCrossDsoCfiTypeId(MD); 27940b57cec5SDimitry Andric if (CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) { 27950b57cec5SDimitry Andric EmitCfiSlowPathCheck(M, TypeTest, CrossDsoTypeId, CastedVTable, StaticData); 27960b57cec5SDimitry Andric return; 27970b57cec5SDimitry Andric } 27980b57cec5SDimitry Andric 27990b57cec5SDimitry Andric if (CGM.getCodeGenOpts().SanitizeTrap.has(M)) { 2800e8d8bef9SDimitry Andric EmitTrapCheck(TypeTest, SanitizerHandler::CFICheckFail); 28010b57cec5SDimitry Andric return; 28020b57cec5SDimitry Andric } 28030b57cec5SDimitry Andric 28040b57cec5SDimitry Andric llvm::Value *AllVtables = llvm::MetadataAsValue::get( 28050b57cec5SDimitry Andric CGM.getLLVMContext(), 28060b57cec5SDimitry Andric llvm::MDString::get(CGM.getLLVMContext(), "all-vtables")); 28070b57cec5SDimitry Andric llvm::Value *ValidVtable = Builder.CreateCall( 28080b57cec5SDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, AllVtables}); 28090b57cec5SDimitry Andric EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail, 28100b57cec5SDimitry Andric StaticData, {CastedVTable, ValidVtable}); 28110b57cec5SDimitry Andric } 28120b57cec5SDimitry Andric 28130b57cec5SDimitry Andric bool CodeGenFunction::ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD) { 28140b57cec5SDimitry Andric if (!CGM.getCodeGenOpts().WholeProgramVTables || 28150b57cec5SDimitry Andric !CGM.HasHiddenLTOVisibility(RD)) 28160b57cec5SDimitry Andric return false; 28170b57cec5SDimitry Andric 2818a7dea167SDimitry Andric if (CGM.getCodeGenOpts().VirtualFunctionElimination) 2819a7dea167SDimitry Andric return true; 2820a7dea167SDimitry Andric 2821a7dea167SDimitry Andric if (!SanOpts.has(SanitizerKind::CFIVCall) || 2822a7dea167SDimitry Andric !CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIVCall)) 2823a7dea167SDimitry Andric return false; 2824a7dea167SDimitry Andric 28250b57cec5SDimitry Andric std::string TypeName = RD->getQualifiedNameAsString(); 2826fe6060f1SDimitry Andric return !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall, 2827fe6060f1SDimitry Andric TypeName); 28280b57cec5SDimitry Andric } 28290b57cec5SDimitry Andric 28300b57cec5SDimitry Andric llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad( 28310b57cec5SDimitry Andric const CXXRecordDecl *RD, llvm::Value *VTable, uint64_t VTableByteOffset) { 28320b57cec5SDimitry Andric SanitizerScope SanScope(this); 28330b57cec5SDimitry Andric 28340b57cec5SDimitry Andric EmitSanitizerStatReport(llvm::SanStat_CFI_VCall); 28350b57cec5SDimitry Andric 28360b57cec5SDimitry Andric llvm::Metadata *MD = 28370b57cec5SDimitry Andric CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)); 28380b57cec5SDimitry Andric llvm::Value *TypeId = llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD); 28390b57cec5SDimitry Andric 28400b57cec5SDimitry Andric llvm::Value *CastedVTable = Builder.CreateBitCast(VTable, Int8PtrTy); 28410b57cec5SDimitry Andric llvm::Value *CheckedLoad = Builder.CreateCall( 28420b57cec5SDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::type_checked_load), 28430b57cec5SDimitry Andric {CastedVTable, llvm::ConstantInt::get(Int32Ty, VTableByteOffset), 28440b57cec5SDimitry Andric TypeId}); 28450b57cec5SDimitry Andric llvm::Value *CheckResult = Builder.CreateExtractValue(CheckedLoad, 1); 28460b57cec5SDimitry Andric 2847a7dea167SDimitry Andric std::string TypeName = RD->getQualifiedNameAsString(); 2848a7dea167SDimitry Andric if (SanOpts.has(SanitizerKind::CFIVCall) && 2849fe6060f1SDimitry Andric !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall, 2850fe6060f1SDimitry Andric TypeName)) { 28510b57cec5SDimitry Andric EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIVCall), 2852a7dea167SDimitry Andric SanitizerHandler::CFICheckFail, {}, {}); 2853a7dea167SDimitry Andric } 28540b57cec5SDimitry Andric 285504eeddc0SDimitry Andric return Builder.CreateBitCast(Builder.CreateExtractValue(CheckedLoad, 0), 285604eeddc0SDimitry Andric VTable->getType()->getPointerElementType()); 28570b57cec5SDimitry Andric } 28580b57cec5SDimitry Andric 28590b57cec5SDimitry Andric void CodeGenFunction::EmitForwardingCallToLambda( 28600b57cec5SDimitry Andric const CXXMethodDecl *callOperator, 28610b57cec5SDimitry Andric CallArgList &callArgs) { 28620b57cec5SDimitry Andric // Get the address of the call operator. 28630b57cec5SDimitry Andric const CGFunctionInfo &calleeFnInfo = 28640b57cec5SDimitry Andric CGM.getTypes().arrangeCXXMethodDeclaration(callOperator); 28650b57cec5SDimitry Andric llvm::Constant *calleePtr = 28660b57cec5SDimitry Andric CGM.GetAddrOfFunction(GlobalDecl(callOperator), 28670b57cec5SDimitry Andric CGM.getTypes().GetFunctionType(calleeFnInfo)); 28680b57cec5SDimitry Andric 28690b57cec5SDimitry Andric // Prepare the return slot. 28700b57cec5SDimitry Andric const FunctionProtoType *FPT = 28710b57cec5SDimitry Andric callOperator->getType()->castAs<FunctionProtoType>(); 28720b57cec5SDimitry Andric QualType resultType = FPT->getReturnType(); 28730b57cec5SDimitry Andric ReturnValueSlot returnSlot; 28740b57cec5SDimitry Andric if (!resultType->isVoidType() && 28750b57cec5SDimitry Andric calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect && 28760b57cec5SDimitry Andric !hasScalarEvaluationKind(calleeFnInfo.getReturnType())) 28775ffd83dbSDimitry Andric returnSlot = 28785ffd83dbSDimitry Andric ReturnValueSlot(ReturnValue, resultType.isVolatileQualified(), 28795ffd83dbSDimitry Andric /*IsUnused=*/false, /*IsExternallyDestructed=*/true); 28800b57cec5SDimitry Andric 28810b57cec5SDimitry Andric // We don't need to separately arrange the call arguments because 28820b57cec5SDimitry Andric // the call can't be variadic anyway --- it's impossible to forward 28830b57cec5SDimitry Andric // variadic arguments. 28840b57cec5SDimitry Andric 28850b57cec5SDimitry Andric // Now emit our call. 28860b57cec5SDimitry Andric auto callee = CGCallee::forDirect(calleePtr, GlobalDecl(callOperator)); 28870b57cec5SDimitry Andric RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs); 28880b57cec5SDimitry Andric 28890b57cec5SDimitry Andric // If necessary, copy the returned value into the slot. 28900b57cec5SDimitry Andric if (!resultType->isVoidType() && returnSlot.isNull()) { 28910b57cec5SDimitry Andric if (getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType()) { 28920b57cec5SDimitry Andric RV = RValue::get(EmitARCRetainAutoreleasedReturnValue(RV.getScalarVal())); 28930b57cec5SDimitry Andric } 28940b57cec5SDimitry Andric EmitReturnOfRValue(RV, resultType); 28950b57cec5SDimitry Andric } else 28960b57cec5SDimitry Andric EmitBranchThroughCleanup(ReturnBlock); 28970b57cec5SDimitry Andric } 28980b57cec5SDimitry Andric 28990b57cec5SDimitry Andric void CodeGenFunction::EmitLambdaBlockInvokeBody() { 29000b57cec5SDimitry Andric const BlockDecl *BD = BlockInfo->getBlockDecl(); 29010b57cec5SDimitry Andric const VarDecl *variable = BD->capture_begin()->getVariable(); 29020b57cec5SDimitry Andric const CXXRecordDecl *Lambda = variable->getType()->getAsCXXRecordDecl(); 29030b57cec5SDimitry Andric const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator(); 29040b57cec5SDimitry Andric 29050b57cec5SDimitry Andric if (CallOp->isVariadic()) { 29060b57cec5SDimitry Andric // FIXME: Making this work correctly is nasty because it requires either 29070b57cec5SDimitry Andric // cloning the body of the call operator or making the call operator 29080b57cec5SDimitry Andric // forward. 29090b57cec5SDimitry Andric CGM.ErrorUnsupported(CurCodeDecl, "lambda conversion to variadic function"); 29100b57cec5SDimitry Andric return; 29110b57cec5SDimitry Andric } 29120b57cec5SDimitry Andric 29130b57cec5SDimitry Andric // Start building arguments for forwarding call 29140b57cec5SDimitry Andric CallArgList CallArgs; 29150b57cec5SDimitry Andric 29160b57cec5SDimitry Andric QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 29170b57cec5SDimitry Andric Address ThisPtr = GetAddrOfBlockDecl(variable); 29180b57cec5SDimitry Andric CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType); 29190b57cec5SDimitry Andric 29200b57cec5SDimitry Andric // Add the rest of the parameters. 29210b57cec5SDimitry Andric for (auto param : BD->parameters()) 29220b57cec5SDimitry Andric EmitDelegateCallArg(CallArgs, param, param->getBeginLoc()); 29230b57cec5SDimitry Andric 29240b57cec5SDimitry Andric assert(!Lambda->isGenericLambda() && 29250b57cec5SDimitry Andric "generic lambda interconversion to block not implemented"); 29260b57cec5SDimitry Andric EmitForwardingCallToLambda(CallOp, CallArgs); 29270b57cec5SDimitry Andric } 29280b57cec5SDimitry Andric 29290b57cec5SDimitry Andric void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD) { 29300b57cec5SDimitry Andric const CXXRecordDecl *Lambda = MD->getParent(); 29310b57cec5SDimitry Andric 29320b57cec5SDimitry Andric // Start building arguments for forwarding call 29330b57cec5SDimitry Andric CallArgList CallArgs; 29340b57cec5SDimitry Andric 29350b57cec5SDimitry Andric QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 29360b57cec5SDimitry Andric llvm::Value *ThisPtr = llvm::UndefValue::get(getTypes().ConvertType(ThisType)); 29370b57cec5SDimitry Andric CallArgs.add(RValue::get(ThisPtr), ThisType); 29380b57cec5SDimitry Andric 29390b57cec5SDimitry Andric // Add the rest of the parameters. 29400b57cec5SDimitry Andric for (auto Param : MD->parameters()) 29410b57cec5SDimitry Andric EmitDelegateCallArg(CallArgs, Param, Param->getBeginLoc()); 29420b57cec5SDimitry Andric 29430b57cec5SDimitry Andric const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator(); 29440b57cec5SDimitry Andric // For a generic lambda, find the corresponding call operator specialization 29450b57cec5SDimitry Andric // to which the call to the static-invoker shall be forwarded. 29460b57cec5SDimitry Andric if (Lambda->isGenericLambda()) { 29470b57cec5SDimitry Andric assert(MD->isFunctionTemplateSpecialization()); 29480b57cec5SDimitry Andric const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs(); 29490b57cec5SDimitry Andric FunctionTemplateDecl *CallOpTemplate = CallOp->getDescribedFunctionTemplate(); 29500b57cec5SDimitry Andric void *InsertPos = nullptr; 29510b57cec5SDimitry Andric FunctionDecl *CorrespondingCallOpSpecialization = 29520b57cec5SDimitry Andric CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos); 29530b57cec5SDimitry Andric assert(CorrespondingCallOpSpecialization); 29540b57cec5SDimitry Andric CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization); 29550b57cec5SDimitry Andric } 29560b57cec5SDimitry Andric EmitForwardingCallToLambda(CallOp, CallArgs); 29570b57cec5SDimitry Andric } 29580b57cec5SDimitry Andric 29590b57cec5SDimitry Andric void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) { 29600b57cec5SDimitry Andric if (MD->isVariadic()) { 29610b57cec5SDimitry Andric // FIXME: Making this work correctly is nasty because it requires either 29620b57cec5SDimitry Andric // cloning the body of the call operator or making the call operator forward. 29630b57cec5SDimitry Andric CGM.ErrorUnsupported(MD, "lambda conversion to variadic function"); 29640b57cec5SDimitry Andric return; 29650b57cec5SDimitry Andric } 29660b57cec5SDimitry Andric 29670b57cec5SDimitry Andric EmitLambdaDelegatingInvokeBody(MD); 29680b57cec5SDimitry Andric } 2969