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" 315f757f3fSDimitry Andric #include "llvm/Support/SaveAndRestore.h" 320b57cec5SDimitry Andric #include "llvm/Transforms/Utils/SanitizerStats.h" 33bdd1243dSDimitry Andric #include <optional> 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric using namespace clang; 360b57cec5SDimitry Andric using namespace CodeGen; 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric /// Return the best known alignment for an unknown pointer to a 390b57cec5SDimitry Andric /// particular class. 400b57cec5SDimitry Andric CharUnits CodeGenModule::getClassPointerAlignment(const CXXRecordDecl *RD) { 415ffd83dbSDimitry Andric if (!RD->hasDefinition()) 420b57cec5SDimitry Andric return CharUnits::One(); // Hopefully won't be used anywhere. 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric auto &layout = getContext().getASTRecordLayout(RD); 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric // If the class is final, then we know that the pointer points to an 470b57cec5SDimitry Andric // object of that type and can use the full alignment. 485ffd83dbSDimitry Andric if (RD->isEffectivelyFinal()) 490b57cec5SDimitry Andric return layout.getAlignment(); 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric // Otherwise, we have to assume it could be a subclass. 520b57cec5SDimitry Andric return layout.getNonVirtualAlignment(); 530b57cec5SDimitry Andric } 545ffd83dbSDimitry Andric 555ffd83dbSDimitry Andric /// Return the smallest possible amount of storage that might be allocated 565ffd83dbSDimitry Andric /// starting from the beginning of an object of a particular class. 575ffd83dbSDimitry Andric /// 585ffd83dbSDimitry Andric /// This may be smaller than sizeof(RD) if RD has virtual base classes. 595ffd83dbSDimitry Andric CharUnits CodeGenModule::getMinimumClassObjectSize(const CXXRecordDecl *RD) { 605ffd83dbSDimitry Andric if (!RD->hasDefinition()) 615ffd83dbSDimitry Andric return CharUnits::One(); 625ffd83dbSDimitry Andric 635ffd83dbSDimitry Andric auto &layout = getContext().getASTRecordLayout(RD); 645ffd83dbSDimitry Andric 655ffd83dbSDimitry Andric // If the class is final, then we know that the pointer points to an 665ffd83dbSDimitry Andric // object of that type and can use the full alignment. 675ffd83dbSDimitry Andric if (RD->isEffectivelyFinal()) 685ffd83dbSDimitry Andric return layout.getSize(); 695ffd83dbSDimitry Andric 705ffd83dbSDimitry Andric // Otherwise, we have to assume it could be a subclass. 715ffd83dbSDimitry Andric return std::max(layout.getNonVirtualSize(), CharUnits::One()); 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric /// Return the best known alignment for a pointer to a virtual base, 750b57cec5SDimitry Andric /// given the alignment of a pointer to the derived class. 760b57cec5SDimitry Andric CharUnits CodeGenModule::getVBaseAlignment(CharUnits actualDerivedAlign, 770b57cec5SDimitry Andric const CXXRecordDecl *derivedClass, 780b57cec5SDimitry Andric const CXXRecordDecl *vbaseClass) { 790b57cec5SDimitry Andric // The basic idea here is that an underaligned derived pointer might 800b57cec5SDimitry Andric // indicate an underaligned base pointer. 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric assert(vbaseClass->isCompleteDefinition()); 830b57cec5SDimitry Andric auto &baseLayout = getContext().getASTRecordLayout(vbaseClass); 840b57cec5SDimitry Andric CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment(); 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric return getDynamicOffsetAlignment(actualDerivedAlign, derivedClass, 870b57cec5SDimitry Andric expectedVBaseAlign); 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric CharUnits 910b57cec5SDimitry Andric CodeGenModule::getDynamicOffsetAlignment(CharUnits actualBaseAlign, 920b57cec5SDimitry Andric const CXXRecordDecl *baseDecl, 930b57cec5SDimitry Andric CharUnits expectedTargetAlign) { 940b57cec5SDimitry Andric // If the base is an incomplete type (which is, alas, possible with 950b57cec5SDimitry Andric // member pointers), be pessimistic. 960b57cec5SDimitry Andric if (!baseDecl->isCompleteDefinition()) 970b57cec5SDimitry Andric return std::min(actualBaseAlign, expectedTargetAlign); 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric auto &baseLayout = getContext().getASTRecordLayout(baseDecl); 1000b57cec5SDimitry Andric CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment(); 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric // If the class is properly aligned, assume the target offset is, too. 1030b57cec5SDimitry Andric // 1040b57cec5SDimitry Andric // This actually isn't necessarily the right thing to do --- if the 1050b57cec5SDimitry Andric // class is a complete object, but it's only properly aligned for a 1060b57cec5SDimitry Andric // base subobject, then the alignments of things relative to it are 1070b57cec5SDimitry Andric // probably off as well. (Note that this requires the alignment of 1080b57cec5SDimitry Andric // the target to be greater than the NV alignment of the derived 1090b57cec5SDimitry Andric // class.) 1100b57cec5SDimitry Andric // 1110b57cec5SDimitry Andric // However, our approach to this kind of under-alignment can only 1120b57cec5SDimitry Andric // ever be best effort; after all, we're never going to propagate 1130b57cec5SDimitry Andric // alignments through variables or parameters. Note, in particular, 1140b57cec5SDimitry Andric // that constructing a polymorphic type in an address that's less 1150b57cec5SDimitry Andric // than pointer-aligned will generally trap in the constructor, 1160b57cec5SDimitry Andric // unless we someday add some sort of attribute to change the 1170b57cec5SDimitry Andric // assumed alignment of 'this'. So our goal here is pretty much 1180b57cec5SDimitry Andric // just to allow the user to explicitly say that a pointer is 1190b57cec5SDimitry Andric // under-aligned and then safely access its fields and vtables. 1200b57cec5SDimitry Andric if (actualBaseAlign >= expectedBaseAlign) { 1210b57cec5SDimitry Andric return expectedTargetAlign; 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric // Otherwise, we might be offset by an arbitrary multiple of the 1250b57cec5SDimitry Andric // actual alignment. The correct adjustment is to take the min of 1260b57cec5SDimitry Andric // the two alignments. 1270b57cec5SDimitry Andric return std::min(actualBaseAlign, expectedTargetAlign); 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric Address CodeGenFunction::LoadCXXThisAddress() { 1310b57cec5SDimitry Andric assert(CurFuncDecl && "loading 'this' without a func declaration?"); 1320eae32dcSDimitry Andric auto *MD = cast<CXXMethodDecl>(CurFuncDecl); 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric // Lazily compute CXXThisAlignment. 1350b57cec5SDimitry Andric if (CXXThisAlignment.isZero()) { 1360b57cec5SDimitry Andric // Just use the best known alignment for the parent. 1370b57cec5SDimitry Andric // TODO: if we're currently emitting a complete-object ctor/dtor, 1380b57cec5SDimitry Andric // we can always use the complete-object alignment. 1390eae32dcSDimitry Andric CXXThisAlignment = CGM.getClassPointerAlignment(MD->getParent()); 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1425f757f3fSDimitry Andric llvm::Type *Ty = ConvertType(MD->getFunctionObjectParameterType()); 14306c3fb27SDimitry Andric return Address(LoadCXXThis(), Ty, CXXThisAlignment, KnownNonNull); 1440b57cec5SDimitry Andric } 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric /// Emit the address of a field using a member data pointer. 1470b57cec5SDimitry Andric /// 1480b57cec5SDimitry Andric /// \param E Only used for emergency diagnostics 1490b57cec5SDimitry Andric Address 1500b57cec5SDimitry Andric CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base, 1510b57cec5SDimitry Andric llvm::Value *memberPtr, 1520b57cec5SDimitry Andric const MemberPointerType *memberPtrType, 1530b57cec5SDimitry Andric LValueBaseInfo *BaseInfo, 1540b57cec5SDimitry Andric TBAAAccessInfo *TBAAInfo) { 1550b57cec5SDimitry Andric // Ask the ABI to compute the actual address. 1560b57cec5SDimitry Andric llvm::Value *ptr = 1570b57cec5SDimitry Andric CGM.getCXXABI().EmitMemberDataPointerAddress(*this, E, base, 1580b57cec5SDimitry Andric memberPtr, memberPtrType); 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric QualType memberType = memberPtrType->getPointeeType(); 1615ffd83dbSDimitry Andric CharUnits memberAlign = 1625ffd83dbSDimitry Andric CGM.getNaturalTypeAlignment(memberType, BaseInfo, TBAAInfo); 1630b57cec5SDimitry Andric memberAlign = 1640b57cec5SDimitry Andric CGM.getDynamicOffsetAlignment(base.getAlignment(), 1650b57cec5SDimitry Andric memberPtrType->getClass()->getAsCXXRecordDecl(), 1660b57cec5SDimitry Andric memberAlign); 1671fd87a68SDimitry Andric return Address(ptr, ConvertTypeForMem(memberPtrType->getPointeeType()), 1681fd87a68SDimitry Andric memberAlign); 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric CharUnits CodeGenModule::computeNonVirtualBaseClassOffset( 1720b57cec5SDimitry Andric const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, 1730b57cec5SDimitry Andric CastExpr::path_const_iterator End) { 1740b57cec5SDimitry Andric CharUnits Offset = CharUnits::Zero(); 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric const ASTContext &Context = getContext(); 1770b57cec5SDimitry Andric const CXXRecordDecl *RD = DerivedClass; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric for (CastExpr::path_const_iterator I = Start; I != End; ++I) { 1800b57cec5SDimitry Andric const CXXBaseSpecifier *Base = *I; 1810b57cec5SDimitry Andric assert(!Base->isVirtual() && "Should not see virtual bases here!"); 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric // Get the layout. 1840b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1850b57cec5SDimitry Andric 186a7dea167SDimitry Andric const auto *BaseDecl = 187a7dea167SDimitry Andric cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl()); 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric // Add the offset. 1900b57cec5SDimitry Andric Offset += Layout.getBaseClassOffset(BaseDecl); 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric RD = BaseDecl; 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric return Offset; 1960b57cec5SDimitry Andric } 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric llvm::Constant * 1990b57cec5SDimitry Andric CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, 2000b57cec5SDimitry Andric CastExpr::path_const_iterator PathBegin, 2010b57cec5SDimitry Andric CastExpr::path_const_iterator PathEnd) { 2020b57cec5SDimitry Andric assert(PathBegin != PathEnd && "Base path should not be empty!"); 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric CharUnits Offset = 2050b57cec5SDimitry Andric computeNonVirtualBaseClassOffset(ClassDecl, PathBegin, PathEnd); 2060b57cec5SDimitry Andric if (Offset.isZero()) 2070b57cec5SDimitry Andric return nullptr; 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric llvm::Type *PtrDiffTy = 2100b57cec5SDimitry Andric Types.ConvertType(getContext().getPointerDiffType()); 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity()); 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric /// Gets the address of a direct base class within a complete object. 2160b57cec5SDimitry Andric /// This should only be used for (1) non-virtual bases or (2) virtual bases 2170b57cec5SDimitry Andric /// when the type is known to be complete (e.g. in complete destructors). 2180b57cec5SDimitry Andric /// 2190b57cec5SDimitry Andric /// The object pointed to by 'This' is assumed to be non-null. 2200b57cec5SDimitry Andric Address 2210b57cec5SDimitry Andric CodeGenFunction::GetAddressOfDirectBaseInCompleteClass(Address This, 2220b57cec5SDimitry Andric const CXXRecordDecl *Derived, 2230b57cec5SDimitry Andric const CXXRecordDecl *Base, 2240b57cec5SDimitry Andric bool BaseIsVirtual) { 2250b57cec5SDimitry Andric // 'this' must be a pointer (in some address space) to Derived. 2260b57cec5SDimitry Andric assert(This.getElementType() == ConvertType(Derived)); 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric // Compute the offset of the virtual base. 2290b57cec5SDimitry Andric CharUnits Offset; 2300b57cec5SDimitry Andric const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived); 2310b57cec5SDimitry Andric if (BaseIsVirtual) 2320b57cec5SDimitry Andric Offset = Layout.getVBaseClassOffset(Base); 2330b57cec5SDimitry Andric else 2340b57cec5SDimitry Andric Offset = Layout.getBaseClassOffset(Base); 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric // Shift and cast down to the base type. 2370b57cec5SDimitry Andric // TODO: for complete types, this should be possible with a GEP. 2380b57cec5SDimitry Andric Address V = This; 2390b57cec5SDimitry Andric if (!Offset.isZero()) { 24006c3fb27SDimitry Andric V = V.withElementType(Int8Ty); 2410b57cec5SDimitry Andric V = Builder.CreateConstInBoundsByteGEP(V, Offset); 2420b57cec5SDimitry Andric } 24306c3fb27SDimitry Andric return V.withElementType(ConvertType(Base)); 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric static Address 2470b57cec5SDimitry Andric ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, 2480b57cec5SDimitry Andric CharUnits nonVirtualOffset, 2490b57cec5SDimitry Andric llvm::Value *virtualOffset, 2500b57cec5SDimitry Andric const CXXRecordDecl *derivedClass, 2510b57cec5SDimitry Andric const CXXRecordDecl *nearestVBase) { 2520b57cec5SDimitry Andric // Assert that we have something to do. 2530b57cec5SDimitry Andric assert(!nonVirtualOffset.isZero() || virtualOffset != nullptr); 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric // Compute the offset from the static and dynamic components. 2560b57cec5SDimitry Andric llvm::Value *baseOffset; 2570b57cec5SDimitry Andric if (!nonVirtualOffset.isZero()) { 2585ffd83dbSDimitry Andric llvm::Type *OffsetType = 2595ffd83dbSDimitry Andric (CGF.CGM.getTarget().getCXXABI().isItaniumFamily() && 2605ffd83dbSDimitry Andric CGF.CGM.getItaniumVTableContext().isRelativeLayout()) 2615ffd83dbSDimitry Andric ? CGF.Int32Ty 2625ffd83dbSDimitry Andric : CGF.PtrDiffTy; 2635ffd83dbSDimitry Andric baseOffset = 2645ffd83dbSDimitry Andric llvm::ConstantInt::get(OffsetType, nonVirtualOffset.getQuantity()); 2650b57cec5SDimitry Andric if (virtualOffset) { 2660b57cec5SDimitry Andric baseOffset = CGF.Builder.CreateAdd(virtualOffset, baseOffset); 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric } else { 2690b57cec5SDimitry Andric baseOffset = virtualOffset; 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric // Apply the base offset. 2730b57cec5SDimitry Andric llvm::Value *ptr = addr.getPointer(); 274fe6060f1SDimitry Andric ptr = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, ptr, baseOffset, "add.ptr"); 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric // If we have a virtual component, the alignment of the result will 2770b57cec5SDimitry Andric // be relative only to the known alignment of that vbase. 2780b57cec5SDimitry Andric CharUnits alignment; 2790b57cec5SDimitry Andric if (virtualOffset) { 2800b57cec5SDimitry Andric assert(nearestVBase && "virtual offset without vbase?"); 2810b57cec5SDimitry Andric alignment = CGF.CGM.getVBaseAlignment(addr.getAlignment(), 2820b57cec5SDimitry Andric derivedClass, nearestVBase); 2830b57cec5SDimitry Andric } else { 2840b57cec5SDimitry Andric alignment = addr.getAlignment(); 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric alignment = alignment.alignmentAtOffset(nonVirtualOffset); 2870b57cec5SDimitry Andric 2880eae32dcSDimitry Andric return Address(ptr, CGF.Int8Ty, alignment); 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric Address CodeGenFunction::GetAddressOfBaseClass( 2920b57cec5SDimitry Andric Address Value, const CXXRecordDecl *Derived, 2930b57cec5SDimitry Andric CastExpr::path_const_iterator PathBegin, 2940b57cec5SDimitry Andric CastExpr::path_const_iterator PathEnd, bool NullCheckValue, 2950b57cec5SDimitry Andric SourceLocation Loc) { 2960b57cec5SDimitry Andric assert(PathBegin != PathEnd && "Base path should not be empty!"); 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric CastExpr::path_const_iterator Start = PathBegin; 2990b57cec5SDimitry Andric const CXXRecordDecl *VBase = nullptr; 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric // Sema has done some convenient canonicalization here: if the 3020b57cec5SDimitry Andric // access path involved any virtual steps, the conversion path will 3030b57cec5SDimitry Andric // *start* with a step down to the correct virtual base subobject, 3040b57cec5SDimitry Andric // and hence will not require any further steps. 3050b57cec5SDimitry Andric if ((*Start)->isVirtual()) { 306a7dea167SDimitry Andric VBase = cast<CXXRecordDecl>( 307a7dea167SDimitry Andric (*Start)->getType()->castAs<RecordType>()->getDecl()); 3080b57cec5SDimitry Andric ++Start; 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric // Compute the static offset of the ultimate destination within its 3120b57cec5SDimitry Andric // allocating subobject (the virtual base, if there is one, or else 3130b57cec5SDimitry Andric // the "complete" object that we see). 3140b57cec5SDimitry Andric CharUnits NonVirtualOffset = CGM.computeNonVirtualBaseClassOffset( 3150b57cec5SDimitry Andric VBase ? VBase : Derived, Start, PathEnd); 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric // If there's a virtual step, we can sometimes "devirtualize" it. 3180b57cec5SDimitry Andric // For now, that's limited to when the derived type is final. 3190b57cec5SDimitry Andric // TODO: "devirtualize" this for accesses to known-complete objects. 3200b57cec5SDimitry Andric if (VBase && Derived->hasAttr<FinalAttr>()) { 3210b57cec5SDimitry Andric const ASTRecordLayout &layout = getContext().getASTRecordLayout(Derived); 3220b57cec5SDimitry Andric CharUnits vBaseOffset = layout.getVBaseClassOffset(VBase); 3230b57cec5SDimitry Andric NonVirtualOffset += vBaseOffset; 3240b57cec5SDimitry Andric VBase = nullptr; // we no longer have a virtual step 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric // Get the base pointer type. 3280eae32dcSDimitry Andric llvm::Type *BaseValueTy = ConvertType((PathEnd[-1])->getType()); 32906c3fb27SDimitry Andric llvm::Type *PtrTy = llvm::PointerType::get( 33006c3fb27SDimitry Andric CGM.getLLVMContext(), Value.getType()->getPointerAddressSpace()); 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric QualType DerivedTy = getContext().getRecordType(Derived); 3330b57cec5SDimitry Andric CharUnits DerivedAlign = CGM.getClassPointerAlignment(Derived); 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric // If the static offset is zero and we don't have a virtual step, 3360b57cec5SDimitry Andric // just do a bitcast; null checks are unnecessary. 3370b57cec5SDimitry Andric if (NonVirtualOffset.isZero() && !VBase) { 3380b57cec5SDimitry Andric if (sanitizePerformTypeCheck()) { 3390b57cec5SDimitry Andric SanitizerSet SkippedChecks; 3400b57cec5SDimitry Andric SkippedChecks.set(SanitizerKind::Null, !NullCheckValue); 3410b57cec5SDimitry Andric EmitTypeCheck(TCK_Upcast, Loc, Value.getPointer(), 3420b57cec5SDimitry Andric DerivedTy, DerivedAlign, SkippedChecks); 3430b57cec5SDimitry Andric } 34406c3fb27SDimitry Andric return Value.withElementType(BaseValueTy); 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric llvm::BasicBlock *origBB = nullptr; 3480b57cec5SDimitry Andric llvm::BasicBlock *endBB = nullptr; 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric // Skip over the offset (and the vtable load) if we're supposed to 3510b57cec5SDimitry Andric // null-check the pointer. 3520b57cec5SDimitry Andric if (NullCheckValue) { 3530b57cec5SDimitry Andric origBB = Builder.GetInsertBlock(); 3540b57cec5SDimitry Andric llvm::BasicBlock *notNullBB = createBasicBlock("cast.notnull"); 3550b57cec5SDimitry Andric endBB = createBasicBlock("cast.end"); 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric llvm::Value *isNull = Builder.CreateIsNull(Value.getPointer()); 3580b57cec5SDimitry Andric Builder.CreateCondBr(isNull, endBB, notNullBB); 3590b57cec5SDimitry Andric EmitBlock(notNullBB); 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric if (sanitizePerformTypeCheck()) { 3630b57cec5SDimitry Andric SanitizerSet SkippedChecks; 3640b57cec5SDimitry Andric SkippedChecks.set(SanitizerKind::Null, true); 3650b57cec5SDimitry Andric EmitTypeCheck(VBase ? TCK_UpcastToVirtualBase : TCK_Upcast, Loc, 3660b57cec5SDimitry Andric Value.getPointer(), DerivedTy, DerivedAlign, SkippedChecks); 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric // Compute the virtual offset. 3700b57cec5SDimitry Andric llvm::Value *VirtualOffset = nullptr; 3710b57cec5SDimitry Andric if (VBase) { 3720b57cec5SDimitry Andric VirtualOffset = 3730b57cec5SDimitry Andric CGM.getCXXABI().GetVirtualBaseClassOffset(*this, Value, Derived, VBase); 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric // Apply both offsets. 3770b57cec5SDimitry Andric Value = ApplyNonVirtualAndVirtualOffset(*this, Value, NonVirtualOffset, 3780b57cec5SDimitry Andric VirtualOffset, Derived, VBase); 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric // Cast to the destination type. 38106c3fb27SDimitry Andric Value = Value.withElementType(BaseValueTy); 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric // Build a phi if we needed a null check. 3840b57cec5SDimitry Andric if (NullCheckValue) { 3850b57cec5SDimitry Andric llvm::BasicBlock *notNullBB = Builder.GetInsertBlock(); 3860b57cec5SDimitry Andric Builder.CreateBr(endBB); 3870b57cec5SDimitry Andric EmitBlock(endBB); 3880b57cec5SDimitry Andric 38906c3fb27SDimitry Andric llvm::PHINode *PHI = Builder.CreatePHI(PtrTy, 2, "cast.result"); 3900b57cec5SDimitry Andric PHI->addIncoming(Value.getPointer(), notNullBB); 39106c3fb27SDimitry Andric PHI->addIncoming(llvm::Constant::getNullValue(PtrTy), origBB); 39206c3fb27SDimitry Andric Value = Value.withPointer(PHI, NotKnownNonNull); 3930b57cec5SDimitry Andric } 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric return Value; 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric Address 3990b57cec5SDimitry Andric CodeGenFunction::GetAddressOfDerivedClass(Address BaseAddr, 4000b57cec5SDimitry Andric const CXXRecordDecl *Derived, 4010b57cec5SDimitry Andric CastExpr::path_const_iterator PathBegin, 4020b57cec5SDimitry Andric CastExpr::path_const_iterator PathEnd, 4030b57cec5SDimitry Andric bool NullCheckValue) { 4040b57cec5SDimitry Andric assert(PathBegin != PathEnd && "Base path should not be empty!"); 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric QualType DerivedTy = 4070b57cec5SDimitry Andric getContext().getCanonicalType(getContext().getTagDeclType(Derived)); 4080eae32dcSDimitry Andric llvm::Type *DerivedValueTy = ConvertType(DerivedTy); 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric llvm::Value *NonVirtualOffset = 4110b57cec5SDimitry Andric CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd); 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric if (!NonVirtualOffset) { 4140b57cec5SDimitry Andric // No offset, we can just cast back. 41506c3fb27SDimitry Andric return BaseAddr.withElementType(DerivedValueTy); 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric llvm::BasicBlock *CastNull = nullptr; 4190b57cec5SDimitry Andric llvm::BasicBlock *CastNotNull = nullptr; 4200b57cec5SDimitry Andric llvm::BasicBlock *CastEnd = nullptr; 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric if (NullCheckValue) { 4230b57cec5SDimitry Andric CastNull = createBasicBlock("cast.null"); 4240b57cec5SDimitry Andric CastNotNull = createBasicBlock("cast.notnull"); 4250b57cec5SDimitry Andric CastEnd = createBasicBlock("cast.end"); 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric llvm::Value *IsNull = Builder.CreateIsNull(BaseAddr.getPointer()); 4280b57cec5SDimitry Andric Builder.CreateCondBr(IsNull, CastNull, CastNotNull); 4290b57cec5SDimitry Andric EmitBlock(CastNotNull); 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric // Apply the offset. 4335f757f3fSDimitry Andric llvm::Value *Value = BaseAddr.getPointer(); 434fe6060f1SDimitry Andric Value = Builder.CreateInBoundsGEP( 435fe6060f1SDimitry Andric Int8Ty, Value, Builder.CreateNeg(NonVirtualOffset), "sub.ptr"); 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric // Produce a PHI if we had a null-check. 4380b57cec5SDimitry Andric if (NullCheckValue) { 4390b57cec5SDimitry Andric Builder.CreateBr(CastEnd); 4400b57cec5SDimitry Andric EmitBlock(CastNull); 4410b57cec5SDimitry Andric Builder.CreateBr(CastEnd); 4420b57cec5SDimitry Andric EmitBlock(CastEnd); 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2); 4450b57cec5SDimitry Andric PHI->addIncoming(Value, CastNotNull); 4460b57cec5SDimitry Andric PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull); 4470b57cec5SDimitry Andric Value = PHI; 4480b57cec5SDimitry Andric } 4490b57cec5SDimitry Andric 4500eae32dcSDimitry Andric return Address(Value, DerivedValueTy, CGM.getClassPointerAlignment(Derived)); 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD, 4540b57cec5SDimitry Andric bool ForVirtualBase, 4550b57cec5SDimitry Andric bool Delegating) { 4560b57cec5SDimitry Andric if (!CGM.getCXXABI().NeedsVTTParameter(GD)) { 4570b57cec5SDimitry Andric // This constructor/destructor does not need a VTT parameter. 4580b57cec5SDimitry Andric return nullptr; 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric const CXXRecordDecl *RD = cast<CXXMethodDecl>(CurCodeDecl)->getParent(); 4620b57cec5SDimitry Andric const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent(); 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andric uint64_t SubVTTIndex; 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric if (Delegating) { 4670b57cec5SDimitry Andric // If this is a delegating constructor call, just load the VTT. 4680b57cec5SDimitry Andric return LoadCXXVTT(); 4690b57cec5SDimitry Andric } else if (RD == Base) { 4700b57cec5SDimitry Andric // If the record matches the base, this is the complete ctor/dtor 4710b57cec5SDimitry Andric // variant calling the base variant in a class with virtual bases. 4720b57cec5SDimitry Andric assert(!CGM.getCXXABI().NeedsVTTParameter(CurGD) && 4730b57cec5SDimitry Andric "doing no-op VTT offset in base dtor/ctor?"); 4740b57cec5SDimitry Andric assert(!ForVirtualBase && "Can't have same class as virtual base!"); 4750b57cec5SDimitry Andric SubVTTIndex = 0; 4760b57cec5SDimitry Andric } else { 4770b57cec5SDimitry Andric const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 4780b57cec5SDimitry Andric CharUnits BaseOffset = ForVirtualBase ? 4790b57cec5SDimitry Andric Layout.getVBaseClassOffset(Base) : 4800b57cec5SDimitry Andric Layout.getBaseClassOffset(Base); 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric SubVTTIndex = 4830b57cec5SDimitry Andric CGM.getVTables().getSubVTTIndex(RD, BaseSubobject(Base, BaseOffset)); 4840b57cec5SDimitry Andric assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!"); 4850b57cec5SDimitry Andric } 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) { 4880b57cec5SDimitry Andric // A VTT parameter was passed to the constructor, use it. 489fe6060f1SDimitry Andric llvm::Value *VTT = LoadCXXVTT(); 490fe6060f1SDimitry Andric return Builder.CreateConstInBoundsGEP1_64(VoidPtrTy, VTT, SubVTTIndex); 4910b57cec5SDimitry Andric } else { 4920b57cec5SDimitry Andric // We're the complete constructor, so get the VTT by name. 493fe6060f1SDimitry Andric llvm::GlobalValue *VTT = CGM.getVTables().GetAddrOfVTT(RD); 494fe6060f1SDimitry Andric return Builder.CreateConstInBoundsGEP2_64( 495fe6060f1SDimitry Andric VTT->getValueType(), VTT, 0, SubVTTIndex); 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric } 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric namespace { 5000b57cec5SDimitry Andric /// Call the destructor for a direct base class. 5010b57cec5SDimitry Andric struct CallBaseDtor final : EHScopeStack::Cleanup { 5020b57cec5SDimitry Andric const CXXRecordDecl *BaseClass; 5030b57cec5SDimitry Andric bool BaseIsVirtual; 5040b57cec5SDimitry Andric CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual) 5050b57cec5SDimitry Andric : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {} 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 5080b57cec5SDimitry Andric const CXXRecordDecl *DerivedClass = 5090b57cec5SDimitry Andric cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent(); 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric const CXXDestructorDecl *D = BaseClass->getDestructor(); 5120b57cec5SDimitry Andric // We are already inside a destructor, so presumably the object being 5130b57cec5SDimitry Andric // destroyed should have the expected type. 5145f757f3fSDimitry Andric QualType ThisTy = D->getFunctionObjectParameterType(); 5150b57cec5SDimitry Andric Address Addr = 5160b57cec5SDimitry Andric CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThisAddress(), 5170b57cec5SDimitry Andric DerivedClass, BaseClass, 5180b57cec5SDimitry Andric BaseIsVirtual); 5190b57cec5SDimitry Andric CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual, 5200b57cec5SDimitry Andric /*Delegating=*/false, Addr, ThisTy); 5210b57cec5SDimitry Andric } 5220b57cec5SDimitry Andric }; 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric /// A visitor which checks whether an initializer uses 'this' in a 5250b57cec5SDimitry Andric /// way which requires the vtable to be properly set. 5260b57cec5SDimitry Andric struct DynamicThisUseChecker : ConstEvaluatedExprVisitor<DynamicThisUseChecker> { 5270b57cec5SDimitry Andric typedef ConstEvaluatedExprVisitor<DynamicThisUseChecker> super; 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric bool UsesThis; 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric DynamicThisUseChecker(const ASTContext &C) : super(C), UsesThis(false) {} 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric // Black-list all explicit and implicit references to 'this'. 5340b57cec5SDimitry Andric // 5350b57cec5SDimitry Andric // Do we need to worry about external references to 'this' derived 5360b57cec5SDimitry Andric // from arbitrary code? If so, then anything which runs arbitrary 5370b57cec5SDimitry Andric // external code might potentially access the vtable. 5380b57cec5SDimitry Andric void VisitCXXThisExpr(const CXXThisExpr *E) { UsesThis = true; } 5390b57cec5SDimitry Andric }; 5400b57cec5SDimitry Andric } // end anonymous namespace 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) { 5430b57cec5SDimitry Andric DynamicThisUseChecker Checker(C); 5440b57cec5SDimitry Andric Checker.Visit(Init); 5450b57cec5SDimitry Andric return Checker.UsesThis; 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric static void EmitBaseInitializer(CodeGenFunction &CGF, 5490b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl, 5500b57cec5SDimitry Andric CXXCtorInitializer *BaseInit) { 5510b57cec5SDimitry Andric assert(BaseInit->isBaseInitializer() && 5520b57cec5SDimitry Andric "Must have base initializer!"); 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric Address ThisPtr = CGF.LoadCXXThisAddress(); 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric const Type *BaseType = BaseInit->getBaseClass(); 557a7dea167SDimitry Andric const auto *BaseClassDecl = 558a7dea167SDimitry Andric cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl()); 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric bool isBaseVirtual = BaseInit->isBaseVirtual(); 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andric // If the initializer for the base (other than the constructor 5630b57cec5SDimitry Andric // itself) accesses 'this' in any way, we need to initialize the 5640b57cec5SDimitry Andric // vtables. 5650b57cec5SDimitry Andric if (BaseInitializerUsesThis(CGF.getContext(), BaseInit->getInit())) 5660b57cec5SDimitry Andric CGF.InitializeVTablePointers(ClassDecl); 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric // We can pretend to be a complete class because it only matters for 5690b57cec5SDimitry Andric // virtual bases, and we only do virtual bases for complete ctors. 5700b57cec5SDimitry Andric Address V = 5710b57cec5SDimitry Andric CGF.GetAddressOfDirectBaseInCompleteClass(ThisPtr, ClassDecl, 5720b57cec5SDimitry Andric BaseClassDecl, 5730b57cec5SDimitry Andric isBaseVirtual); 5740b57cec5SDimitry Andric AggValueSlot AggSlot = 5750b57cec5SDimitry Andric AggValueSlot::forAddr( 5760b57cec5SDimitry Andric V, Qualifiers(), 5770b57cec5SDimitry Andric AggValueSlot::IsDestructed, 5780b57cec5SDimitry Andric AggValueSlot::DoesNotNeedGCBarriers, 5790b57cec5SDimitry Andric AggValueSlot::IsNotAliased, 5800b57cec5SDimitry Andric CGF.getOverlapForBaseInit(ClassDecl, BaseClassDecl, isBaseVirtual)); 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andric CGF.EmitAggExpr(BaseInit->getInit(), AggSlot); 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andric if (CGF.CGM.getLangOpts().Exceptions && 5850b57cec5SDimitry Andric !BaseClassDecl->hasTrivialDestructor()) 5860b57cec5SDimitry Andric CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl, 5870b57cec5SDimitry Andric isBaseVirtual); 5880b57cec5SDimitry Andric } 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric static bool isMemcpyEquivalentSpecialMember(const CXXMethodDecl *D) { 5910b57cec5SDimitry Andric auto *CD = dyn_cast<CXXConstructorDecl>(D); 5920b57cec5SDimitry Andric if (!(CD && CD->isCopyOrMoveConstructor()) && 5930b57cec5SDimitry Andric !D->isCopyAssignmentOperator() && !D->isMoveAssignmentOperator()) 5940b57cec5SDimitry Andric return false; 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric // We can emit a memcpy for a trivial copy or move constructor/assignment. 5970b57cec5SDimitry Andric if (D->isTrivial() && !D->getParent()->mayInsertExtraPadding()) 5980b57cec5SDimitry Andric return true; 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric // We *must* emit a memcpy for a defaulted union copy or move op. 6010b57cec5SDimitry Andric if (D->getParent()->isUnion() && D->isDefaulted()) 6020b57cec5SDimitry Andric return true; 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andric return false; 6050b57cec5SDimitry Andric } 6060b57cec5SDimitry Andric 6070b57cec5SDimitry Andric static void EmitLValueForAnyFieldInitialization(CodeGenFunction &CGF, 6080b57cec5SDimitry Andric CXXCtorInitializer *MemberInit, 6090b57cec5SDimitry Andric LValue &LHS) { 6100b57cec5SDimitry Andric FieldDecl *Field = MemberInit->getAnyMember(); 6110b57cec5SDimitry Andric if (MemberInit->isIndirectMemberInitializer()) { 6120b57cec5SDimitry Andric // If we are initializing an anonymous union field, drill down to the field. 6130b57cec5SDimitry Andric IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember(); 6140b57cec5SDimitry Andric for (const auto *I : IndirectField->chain()) 6150b57cec5SDimitry Andric LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(I)); 6160b57cec5SDimitry Andric } else { 6170b57cec5SDimitry Andric LHS = CGF.EmitLValueForFieldInitialization(LHS, Field); 6180b57cec5SDimitry Andric } 6190b57cec5SDimitry Andric } 6200b57cec5SDimitry Andric 6210b57cec5SDimitry Andric static void EmitMemberInitializer(CodeGenFunction &CGF, 6220b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl, 6230b57cec5SDimitry Andric CXXCtorInitializer *MemberInit, 6240b57cec5SDimitry Andric const CXXConstructorDecl *Constructor, 6250b57cec5SDimitry Andric FunctionArgList &Args) { 6260b57cec5SDimitry Andric ApplyDebugLocation Loc(CGF, MemberInit->getSourceLocation()); 6270b57cec5SDimitry Andric assert(MemberInit->isAnyMemberInitializer() && 6280b57cec5SDimitry Andric "Must have member initializer!"); 6290b57cec5SDimitry Andric assert(MemberInit->getInit() && "Must have initializer!"); 6300b57cec5SDimitry Andric 6310b57cec5SDimitry Andric // non-static data member initializers. 6320b57cec5SDimitry Andric FieldDecl *Field = MemberInit->getAnyMember(); 6330b57cec5SDimitry Andric QualType FieldType = Field->getType(); 6340b57cec5SDimitry Andric 6350b57cec5SDimitry Andric llvm::Value *ThisPtr = CGF.LoadCXXThis(); 6360b57cec5SDimitry Andric QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 6370b57cec5SDimitry Andric LValue LHS; 6380b57cec5SDimitry Andric 6390b57cec5SDimitry Andric // If a base constructor is being emitted, create an LValue that has the 6400b57cec5SDimitry Andric // non-virtual alignment. 6410b57cec5SDimitry Andric if (CGF.CurGD.getCtorType() == Ctor_Base) 6420b57cec5SDimitry Andric LHS = CGF.MakeNaturalAlignPointeeAddrLValue(ThisPtr, RecordTy); 6430b57cec5SDimitry Andric else 6440b57cec5SDimitry Andric LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy); 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric EmitLValueForAnyFieldInitialization(CGF, MemberInit, LHS); 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric // Special case: if we are in a copy or move constructor, and we are copying 6490b57cec5SDimitry Andric // an array of PODs or classes with trivial copy constructors, ignore the 6500b57cec5SDimitry Andric // AST and perform the copy we know is equivalent. 6510b57cec5SDimitry Andric // FIXME: This is hacky at best... if we had a bit more explicit information 6520b57cec5SDimitry Andric // in the AST, we could generalize it more easily. 6530b57cec5SDimitry Andric const ConstantArrayType *Array 6540b57cec5SDimitry Andric = CGF.getContext().getAsConstantArrayType(FieldType); 6550b57cec5SDimitry Andric if (Array && Constructor->isDefaulted() && 6560b57cec5SDimitry Andric Constructor->isCopyOrMoveConstructor()) { 6570b57cec5SDimitry Andric QualType BaseElementTy = CGF.getContext().getBaseElementType(Array); 6580b57cec5SDimitry Andric CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); 6590b57cec5SDimitry Andric if (BaseElementTy.isPODType(CGF.getContext()) || 6600b57cec5SDimitry Andric (CE && isMemcpyEquivalentSpecialMember(CE->getConstructor()))) { 6610b57cec5SDimitry Andric unsigned SrcArgIndex = 6620b57cec5SDimitry Andric CGF.CGM.getCXXABI().getSrcArgforCopyCtor(Constructor, Args); 6630b57cec5SDimitry Andric llvm::Value *SrcPtr 6640b57cec5SDimitry Andric = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex])); 6650b57cec5SDimitry Andric LValue ThisRHSLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); 6660b57cec5SDimitry Andric LValue Src = CGF.EmitLValueForFieldInitialization(ThisRHSLV, Field); 6670b57cec5SDimitry Andric 6680b57cec5SDimitry Andric // Copy the aggregate. 6690b57cec5SDimitry Andric CGF.EmitAggregateCopy(LHS, Src, FieldType, CGF.getOverlapForFieldInit(Field), 6700b57cec5SDimitry Andric LHS.isVolatileQualified()); 6710b57cec5SDimitry Andric // Ensure that we destroy the objects if an exception is thrown later in 6720b57cec5SDimitry Andric // the constructor. 6730b57cec5SDimitry Andric QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 6740b57cec5SDimitry Andric if (CGF.needsEHCleanup(dtorKind)) 675480093f4SDimitry Andric CGF.pushEHDestroy(dtorKind, LHS.getAddress(CGF), FieldType); 6760b57cec5SDimitry Andric return; 6770b57cec5SDimitry Andric } 6780b57cec5SDimitry Andric } 6790b57cec5SDimitry Andric 6800b57cec5SDimitry Andric CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit()); 6810b57cec5SDimitry Andric } 6820b57cec5SDimitry Andric 6830b57cec5SDimitry Andric void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS, 6840b57cec5SDimitry Andric Expr *Init) { 6850b57cec5SDimitry Andric QualType FieldType = Field->getType(); 6860b57cec5SDimitry Andric switch (getEvaluationKind(FieldType)) { 6870b57cec5SDimitry Andric case TEK_Scalar: 6880b57cec5SDimitry Andric if (LHS.isSimple()) { 6890b57cec5SDimitry Andric EmitExprAsInit(Init, Field, LHS, false); 6900b57cec5SDimitry Andric } else { 6910b57cec5SDimitry Andric RValue RHS = RValue::get(EmitScalarExpr(Init)); 6920b57cec5SDimitry Andric EmitStoreThroughLValue(RHS, LHS); 6930b57cec5SDimitry Andric } 6940b57cec5SDimitry Andric break; 6950b57cec5SDimitry Andric case TEK_Complex: 6960b57cec5SDimitry Andric EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true); 6970b57cec5SDimitry Andric break; 6980b57cec5SDimitry Andric case TEK_Aggregate: { 699480093f4SDimitry Andric AggValueSlot Slot = AggValueSlot::forLValue( 700480093f4SDimitry Andric LHS, *this, AggValueSlot::IsDestructed, 701480093f4SDimitry Andric AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, 702480093f4SDimitry Andric getOverlapForFieldInit(Field), AggValueSlot::IsNotZeroed, 7030b57cec5SDimitry Andric // Checks are made by the code that calls constructor. 7040b57cec5SDimitry Andric AggValueSlot::IsSanitizerChecked); 7050b57cec5SDimitry Andric EmitAggExpr(Init, Slot); 7060b57cec5SDimitry Andric break; 7070b57cec5SDimitry Andric } 7080b57cec5SDimitry Andric } 7090b57cec5SDimitry Andric 7100b57cec5SDimitry Andric // Ensure that we destroy this object if an exception is thrown 7110b57cec5SDimitry Andric // later in the constructor. 7120b57cec5SDimitry Andric QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 7130b57cec5SDimitry Andric if (needsEHCleanup(dtorKind)) 714480093f4SDimitry Andric pushEHDestroy(dtorKind, LHS.getAddress(*this), FieldType); 7150b57cec5SDimitry Andric } 7160b57cec5SDimitry Andric 7170b57cec5SDimitry Andric /// Checks whether the given constructor is a valid subject for the 7180b57cec5SDimitry Andric /// complete-to-base constructor delegation optimization, i.e. 7190b57cec5SDimitry Andric /// emitting the complete constructor as a simple call to the base 7200b57cec5SDimitry Andric /// constructor. 7210b57cec5SDimitry Andric bool CodeGenFunction::IsConstructorDelegationValid( 7220b57cec5SDimitry Andric const CXXConstructorDecl *Ctor) { 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric // Currently we disable the optimization for classes with virtual 7250b57cec5SDimitry Andric // bases because (1) the addresses of parameter variables need to be 7260b57cec5SDimitry Andric // consistent across all initializers but (2) the delegate function 7270b57cec5SDimitry Andric // call necessarily creates a second copy of the parameter variable. 7280b57cec5SDimitry Andric // 7290b57cec5SDimitry Andric // The limiting example (purely theoretical AFAIK): 7300b57cec5SDimitry Andric // struct A { A(int &c) { c++; } }; 7310b57cec5SDimitry Andric // struct B : virtual A { 7320b57cec5SDimitry Andric // B(int count) : A(count) { printf("%d\n", count); } 7330b57cec5SDimitry Andric // }; 7340b57cec5SDimitry Andric // ...although even this example could in principle be emitted as a 7350b57cec5SDimitry Andric // delegation since the address of the parameter doesn't escape. 7360b57cec5SDimitry Andric if (Ctor->getParent()->getNumVBases()) { 7370b57cec5SDimitry Andric // TODO: white-list trivial vbase initializers. This case wouldn't 7380b57cec5SDimitry Andric // be subject to the restrictions below. 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric // TODO: white-list cases where: 7410b57cec5SDimitry Andric // - there are no non-reference parameters to the constructor 7420b57cec5SDimitry Andric // - the initializers don't access any non-reference parameters 7430b57cec5SDimitry Andric // - the initializers don't take the address of non-reference 7440b57cec5SDimitry Andric // parameters 7450b57cec5SDimitry Andric // - etc. 7460b57cec5SDimitry Andric // If we ever add any of the above cases, remember that: 7475ffd83dbSDimitry Andric // - function-try-blocks will always exclude this optimization 7480b57cec5SDimitry Andric // - we need to perform the constructor prologue and cleanup in 7490b57cec5SDimitry Andric // EmitConstructorBody. 7500b57cec5SDimitry Andric 7510b57cec5SDimitry Andric return false; 7520b57cec5SDimitry Andric } 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andric // We also disable the optimization for variadic functions because 7550b57cec5SDimitry Andric // it's impossible to "re-pass" varargs. 756a7dea167SDimitry Andric if (Ctor->getType()->castAs<FunctionProtoType>()->isVariadic()) 7570b57cec5SDimitry Andric return false; 7580b57cec5SDimitry Andric 7590b57cec5SDimitry Andric // FIXME: Decide if we can do a delegation of a delegating constructor. 7600b57cec5SDimitry Andric if (Ctor->isDelegatingConstructor()) 7610b57cec5SDimitry Andric return false; 7620b57cec5SDimitry Andric 7630b57cec5SDimitry Andric return true; 7640b57cec5SDimitry Andric } 7650b57cec5SDimitry Andric 7660b57cec5SDimitry Andric // Emit code in ctor (Prologue==true) or dtor (Prologue==false) 7670b57cec5SDimitry Andric // to poison the extra field paddings inserted under 7680b57cec5SDimitry Andric // -fsanitize-address-field-padding=1|2. 7690b57cec5SDimitry Andric void CodeGenFunction::EmitAsanPrologueOrEpilogue(bool Prologue) { 7700b57cec5SDimitry Andric ASTContext &Context = getContext(); 7710b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = 7720b57cec5SDimitry Andric Prologue ? cast<CXXConstructorDecl>(CurGD.getDecl())->getParent() 7730b57cec5SDimitry Andric : cast<CXXDestructorDecl>(CurGD.getDecl())->getParent(); 7740b57cec5SDimitry Andric if (!ClassDecl->mayInsertExtraPadding()) return; 7750b57cec5SDimitry Andric 7760b57cec5SDimitry Andric struct SizeAndOffset { 7770b57cec5SDimitry Andric uint64_t Size; 7780b57cec5SDimitry Andric uint64_t Offset; 7790b57cec5SDimitry Andric }; 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric unsigned PtrSize = CGM.getDataLayout().getPointerSizeInBits(); 7820b57cec5SDimitry Andric const ASTRecordLayout &Info = Context.getASTRecordLayout(ClassDecl); 7830b57cec5SDimitry Andric 7840b57cec5SDimitry Andric // Populate sizes and offsets of fields. 7850b57cec5SDimitry Andric SmallVector<SizeAndOffset, 16> SSV(Info.getFieldCount()); 7860b57cec5SDimitry Andric for (unsigned i = 0, e = Info.getFieldCount(); i != e; ++i) 7870b57cec5SDimitry Andric SSV[i].Offset = 7880b57cec5SDimitry Andric Context.toCharUnitsFromBits(Info.getFieldOffset(i)).getQuantity(); 7890b57cec5SDimitry Andric 7900b57cec5SDimitry Andric size_t NumFields = 0; 7910b57cec5SDimitry Andric for (const auto *Field : ClassDecl->fields()) { 7920b57cec5SDimitry Andric const FieldDecl *D = Field; 793e8d8bef9SDimitry Andric auto FieldInfo = Context.getTypeInfoInChars(D->getType()); 794e8d8bef9SDimitry Andric CharUnits FieldSize = FieldInfo.Width; 7950b57cec5SDimitry Andric assert(NumFields < SSV.size()); 7960b57cec5SDimitry Andric SSV[NumFields].Size = D->isBitField() ? 0 : FieldSize.getQuantity(); 7970b57cec5SDimitry Andric NumFields++; 7980b57cec5SDimitry Andric } 7990b57cec5SDimitry Andric assert(NumFields == SSV.size()); 8000b57cec5SDimitry Andric if (SSV.size() <= 1) return; 8010b57cec5SDimitry Andric 8020b57cec5SDimitry Andric // We will insert calls to __asan_* run-time functions. 8030b57cec5SDimitry Andric // LLVM AddressSanitizer pass may decide to inline them later. 8040b57cec5SDimitry Andric llvm::Type *Args[2] = {IntPtrTy, IntPtrTy}; 8050b57cec5SDimitry Andric llvm::FunctionType *FTy = 8060b57cec5SDimitry Andric llvm::FunctionType::get(CGM.VoidTy, Args, false); 8070b57cec5SDimitry Andric llvm::FunctionCallee F = CGM.CreateRuntimeFunction( 8080b57cec5SDimitry Andric FTy, Prologue ? "__asan_poison_intra_object_redzone" 8090b57cec5SDimitry Andric : "__asan_unpoison_intra_object_redzone"); 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric llvm::Value *ThisPtr = LoadCXXThis(); 8120b57cec5SDimitry Andric ThisPtr = Builder.CreatePtrToInt(ThisPtr, IntPtrTy); 8130b57cec5SDimitry Andric uint64_t TypeSize = Info.getNonVirtualSize().getQuantity(); 8140b57cec5SDimitry Andric // For each field check if it has sufficient padding, 8150b57cec5SDimitry Andric // if so (un)poison it with a call. 8160b57cec5SDimitry Andric for (size_t i = 0; i < SSV.size(); i++) { 8170b57cec5SDimitry Andric uint64_t AsanAlignment = 8; 8180b57cec5SDimitry Andric uint64_t NextField = i == SSV.size() - 1 ? TypeSize : SSV[i + 1].Offset; 8190b57cec5SDimitry Andric uint64_t PoisonSize = NextField - SSV[i].Offset - SSV[i].Size; 8200b57cec5SDimitry Andric uint64_t EndOffset = SSV[i].Offset + SSV[i].Size; 8210b57cec5SDimitry Andric if (PoisonSize < AsanAlignment || !SSV[i].Size || 8220b57cec5SDimitry Andric (NextField % AsanAlignment) != 0) 8230b57cec5SDimitry Andric continue; 8240b57cec5SDimitry Andric Builder.CreateCall( 8250b57cec5SDimitry Andric F, {Builder.CreateAdd(ThisPtr, Builder.getIntN(PtrSize, EndOffset)), 8260b57cec5SDimitry Andric Builder.getIntN(PtrSize, PoisonSize)}); 8270b57cec5SDimitry Andric } 8280b57cec5SDimitry Andric } 8290b57cec5SDimitry Andric 8300b57cec5SDimitry Andric /// EmitConstructorBody - Emits the body of the current constructor. 8310b57cec5SDimitry Andric void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) { 8320b57cec5SDimitry Andric EmitAsanPrologueOrEpilogue(true); 8330b57cec5SDimitry Andric const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl()); 8340b57cec5SDimitry Andric CXXCtorType CtorType = CurGD.getCtorType(); 8350b57cec5SDimitry Andric 8360b57cec5SDimitry Andric assert((CGM.getTarget().getCXXABI().hasConstructorVariants() || 8370b57cec5SDimitry Andric CtorType == Ctor_Complete) && 8380b57cec5SDimitry Andric "can only generate complete ctor for this ABI"); 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andric // Before we go any further, try the complete->base constructor 8410b57cec5SDimitry Andric // delegation optimization. 8420b57cec5SDimitry Andric if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor) && 8430b57cec5SDimitry Andric CGM.getTarget().getCXXABI().hasConstructorVariants()) { 8440b57cec5SDimitry Andric EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args, Ctor->getEndLoc()); 8450b57cec5SDimitry Andric return; 8460b57cec5SDimitry Andric } 8470b57cec5SDimitry Andric 8480b57cec5SDimitry Andric const FunctionDecl *Definition = nullptr; 8490b57cec5SDimitry Andric Stmt *Body = Ctor->getBody(Definition); 8500b57cec5SDimitry Andric assert(Definition == Ctor && "emitting wrong constructor body"); 8510b57cec5SDimitry Andric 8520b57cec5SDimitry Andric // Enter the function-try-block before the constructor prologue if 8530b57cec5SDimitry Andric // applicable. 8540b57cec5SDimitry Andric bool IsTryBody = (Body && isa<CXXTryStmt>(Body)); 8550b57cec5SDimitry Andric if (IsTryBody) 8560b57cec5SDimitry Andric EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 8570b57cec5SDimitry Andric 8580b57cec5SDimitry Andric incrementProfileCounter(Body); 8590b57cec5SDimitry Andric 8600b57cec5SDimitry Andric RunCleanupsScope RunCleanups(*this); 8610b57cec5SDimitry Andric 8620b57cec5SDimitry Andric // TODO: in restricted cases, we can emit the vbase initializers of 8630b57cec5SDimitry Andric // a complete ctor and then delegate to the base ctor. 8640b57cec5SDimitry Andric 8650b57cec5SDimitry Andric // Emit the constructor prologue, i.e. the base and member 8660b57cec5SDimitry Andric // initializers. 8670b57cec5SDimitry Andric EmitCtorPrologue(Ctor, CtorType, Args); 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric // Emit the body of the statement. 8700b57cec5SDimitry Andric if (IsTryBody) 8710b57cec5SDimitry Andric EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 8720b57cec5SDimitry Andric else if (Body) 8730b57cec5SDimitry Andric EmitStmt(Body); 8740b57cec5SDimitry Andric 8750b57cec5SDimitry Andric // Emit any cleanup blocks associated with the member or base 8760b57cec5SDimitry Andric // initializers, which includes (along the exceptional path) the 8770b57cec5SDimitry Andric // destructors for those members and bases that were fully 8780b57cec5SDimitry Andric // constructed. 8790b57cec5SDimitry Andric RunCleanups.ForceCleanup(); 8800b57cec5SDimitry Andric 8810b57cec5SDimitry Andric if (IsTryBody) 8820b57cec5SDimitry Andric ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric 8850b57cec5SDimitry Andric namespace { 8860b57cec5SDimitry Andric /// RAII object to indicate that codegen is copying the value representation 8870b57cec5SDimitry Andric /// instead of the object representation. Useful when copying a struct or 8880b57cec5SDimitry Andric /// class which has uninitialized members and we're only performing 8890b57cec5SDimitry Andric /// lvalue-to-rvalue conversion on the object but not its members. 8900b57cec5SDimitry Andric class CopyingValueRepresentation { 8910b57cec5SDimitry Andric public: 8920b57cec5SDimitry Andric explicit CopyingValueRepresentation(CodeGenFunction &CGF) 8930b57cec5SDimitry Andric : CGF(CGF), OldSanOpts(CGF.SanOpts) { 8940b57cec5SDimitry Andric CGF.SanOpts.set(SanitizerKind::Bool, false); 8950b57cec5SDimitry Andric CGF.SanOpts.set(SanitizerKind::Enum, false); 8960b57cec5SDimitry Andric } 8970b57cec5SDimitry Andric ~CopyingValueRepresentation() { 8980b57cec5SDimitry Andric CGF.SanOpts = OldSanOpts; 8990b57cec5SDimitry Andric } 9000b57cec5SDimitry Andric private: 9010b57cec5SDimitry Andric CodeGenFunction &CGF; 9020b57cec5SDimitry Andric SanitizerSet OldSanOpts; 9030b57cec5SDimitry Andric }; 9040b57cec5SDimitry Andric } // end anonymous namespace 9050b57cec5SDimitry Andric 9060b57cec5SDimitry Andric namespace { 9070b57cec5SDimitry Andric class FieldMemcpyizer { 9080b57cec5SDimitry Andric public: 9090b57cec5SDimitry Andric FieldMemcpyizer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, 9100b57cec5SDimitry Andric const VarDecl *SrcRec) 9110b57cec5SDimitry Andric : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec), 9120b57cec5SDimitry Andric RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)), 9130b57cec5SDimitry Andric FirstField(nullptr), LastField(nullptr), FirstFieldOffset(0), 9140b57cec5SDimitry Andric LastFieldOffset(0), LastAddedFieldIndex(0) {} 9150b57cec5SDimitry Andric 9160b57cec5SDimitry Andric bool isMemcpyableField(FieldDecl *F) const { 9170b57cec5SDimitry Andric // Never memcpy fields when we are adding poisoned paddings. 9180b57cec5SDimitry Andric if (CGF.getContext().getLangOpts().SanitizeAddressFieldPadding) 9190b57cec5SDimitry Andric return false; 9200b57cec5SDimitry Andric Qualifiers Qual = F->getType().getQualifiers(); 9210b57cec5SDimitry Andric if (Qual.hasVolatile() || Qual.hasObjCLifetime()) 9220b57cec5SDimitry Andric return false; 9230b57cec5SDimitry Andric return true; 9240b57cec5SDimitry Andric } 9250b57cec5SDimitry Andric 9260b57cec5SDimitry Andric void addMemcpyableField(FieldDecl *F) { 927480093f4SDimitry Andric if (F->isZeroSize(CGF.getContext())) 928480093f4SDimitry Andric return; 9290b57cec5SDimitry Andric if (!FirstField) 9300b57cec5SDimitry Andric addInitialField(F); 9310b57cec5SDimitry Andric else 9320b57cec5SDimitry Andric addNextField(F); 9330b57cec5SDimitry Andric } 9340b57cec5SDimitry Andric 9350b57cec5SDimitry Andric CharUnits getMemcpySize(uint64_t FirstByteOffset) const { 9360b57cec5SDimitry Andric ASTContext &Ctx = CGF.getContext(); 9370b57cec5SDimitry Andric unsigned LastFieldSize = 9380b57cec5SDimitry Andric LastField->isBitField() 9390b57cec5SDimitry Andric ? LastField->getBitWidthValue(Ctx) 9400b57cec5SDimitry Andric : Ctx.toBits( 941e8d8bef9SDimitry Andric Ctx.getTypeInfoDataSizeInChars(LastField->getType()).Width); 9420b57cec5SDimitry Andric uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize - 9430b57cec5SDimitry Andric FirstByteOffset + Ctx.getCharWidth() - 1; 9440b57cec5SDimitry Andric CharUnits MemcpySize = Ctx.toCharUnitsFromBits(MemcpySizeBits); 9450b57cec5SDimitry Andric return MemcpySize; 9460b57cec5SDimitry Andric } 9470b57cec5SDimitry Andric 9480b57cec5SDimitry Andric void emitMemcpy() { 9490b57cec5SDimitry Andric // Give the subclass a chance to bail out if it feels the memcpy isn't 9500b57cec5SDimitry Andric // worth it (e.g. Hasn't aggregated enough data). 9510b57cec5SDimitry Andric if (!FirstField) { 9520b57cec5SDimitry Andric return; 9530b57cec5SDimitry Andric } 9540b57cec5SDimitry Andric 9550b57cec5SDimitry Andric uint64_t FirstByteOffset; 9560b57cec5SDimitry Andric if (FirstField->isBitField()) { 9570b57cec5SDimitry Andric const CGRecordLayout &RL = 9580b57cec5SDimitry Andric CGF.getTypes().getCGRecordLayout(FirstField->getParent()); 9590b57cec5SDimitry Andric const CGBitFieldInfo &BFInfo = RL.getBitFieldInfo(FirstField); 9600b57cec5SDimitry Andric // FirstFieldOffset is not appropriate for bitfields, 9610b57cec5SDimitry Andric // we need to use the storage offset instead. 9620b57cec5SDimitry Andric FirstByteOffset = CGF.getContext().toBits(BFInfo.StorageOffset); 9630b57cec5SDimitry Andric } else { 9640b57cec5SDimitry Andric FirstByteOffset = FirstFieldOffset; 9650b57cec5SDimitry Andric } 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric CharUnits MemcpySize = getMemcpySize(FirstByteOffset); 9680b57cec5SDimitry Andric QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 9690b57cec5SDimitry Andric Address ThisPtr = CGF.LoadCXXThisAddress(); 9700b57cec5SDimitry Andric LValue DestLV = CGF.MakeAddrLValue(ThisPtr, RecordTy); 9710b57cec5SDimitry Andric LValue Dest = CGF.EmitLValueForFieldInitialization(DestLV, FirstField); 9720b57cec5SDimitry Andric llvm::Value *SrcPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(SrcRec)); 9730b57cec5SDimitry Andric LValue SrcLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy); 9740b57cec5SDimitry Andric LValue Src = CGF.EmitLValueForFieldInitialization(SrcLV, FirstField); 9750b57cec5SDimitry Andric 976480093f4SDimitry Andric emitMemcpyIR( 977480093f4SDimitry Andric Dest.isBitField() ? Dest.getBitFieldAddress() : Dest.getAddress(CGF), 978480093f4SDimitry Andric Src.isBitField() ? Src.getBitFieldAddress() : Src.getAddress(CGF), 9790b57cec5SDimitry Andric MemcpySize); 9800b57cec5SDimitry Andric reset(); 9810b57cec5SDimitry Andric } 9820b57cec5SDimitry Andric 9830b57cec5SDimitry Andric void reset() { 9840b57cec5SDimitry Andric FirstField = nullptr; 9850b57cec5SDimitry Andric } 9860b57cec5SDimitry Andric 9870b57cec5SDimitry Andric protected: 9880b57cec5SDimitry Andric CodeGenFunction &CGF; 9890b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl; 9900b57cec5SDimitry Andric 9910b57cec5SDimitry Andric private: 9920b57cec5SDimitry Andric void emitMemcpyIR(Address DestPtr, Address SrcPtr, CharUnits Size) { 99306c3fb27SDimitry Andric DestPtr = DestPtr.withElementType(CGF.Int8Ty); 99406c3fb27SDimitry Andric SrcPtr = SrcPtr.withElementType(CGF.Int8Ty); 9950b57cec5SDimitry Andric CGF.Builder.CreateMemCpy(DestPtr, SrcPtr, Size.getQuantity()); 9960b57cec5SDimitry Andric } 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric void addInitialField(FieldDecl *F) { 9990b57cec5SDimitry Andric FirstField = F; 10000b57cec5SDimitry Andric LastField = F; 10010b57cec5SDimitry Andric FirstFieldOffset = RecLayout.getFieldOffset(F->getFieldIndex()); 10020b57cec5SDimitry Andric LastFieldOffset = FirstFieldOffset; 10030b57cec5SDimitry Andric LastAddedFieldIndex = F->getFieldIndex(); 10040b57cec5SDimitry Andric } 10050b57cec5SDimitry Andric 10060b57cec5SDimitry Andric void addNextField(FieldDecl *F) { 10070b57cec5SDimitry Andric // For the most part, the following invariant will hold: 10080b57cec5SDimitry Andric // F->getFieldIndex() == LastAddedFieldIndex + 1 10090b57cec5SDimitry Andric // The one exception is that Sema won't add a copy-initializer for an 10100b57cec5SDimitry Andric // unnamed bitfield, which will show up here as a gap in the sequence. 10110b57cec5SDimitry Andric assert(F->getFieldIndex() >= LastAddedFieldIndex + 1 && 10120b57cec5SDimitry Andric "Cannot aggregate fields out of order."); 10130b57cec5SDimitry Andric LastAddedFieldIndex = F->getFieldIndex(); 10140b57cec5SDimitry Andric 10150b57cec5SDimitry Andric // The 'first' and 'last' fields are chosen by offset, rather than field 10160b57cec5SDimitry Andric // index. This allows the code to support bitfields, as well as regular 10170b57cec5SDimitry Andric // fields. 10180b57cec5SDimitry Andric uint64_t FOffset = RecLayout.getFieldOffset(F->getFieldIndex()); 10190b57cec5SDimitry Andric if (FOffset < FirstFieldOffset) { 10200b57cec5SDimitry Andric FirstField = F; 10210b57cec5SDimitry Andric FirstFieldOffset = FOffset; 10220b57cec5SDimitry Andric } else if (FOffset >= LastFieldOffset) { 10230b57cec5SDimitry Andric LastField = F; 10240b57cec5SDimitry Andric LastFieldOffset = FOffset; 10250b57cec5SDimitry Andric } 10260b57cec5SDimitry Andric } 10270b57cec5SDimitry Andric 10280b57cec5SDimitry Andric const VarDecl *SrcRec; 10290b57cec5SDimitry Andric const ASTRecordLayout &RecLayout; 10300b57cec5SDimitry Andric FieldDecl *FirstField; 10310b57cec5SDimitry Andric FieldDecl *LastField; 10320b57cec5SDimitry Andric uint64_t FirstFieldOffset, LastFieldOffset; 10330b57cec5SDimitry Andric unsigned LastAddedFieldIndex; 10340b57cec5SDimitry Andric }; 10350b57cec5SDimitry Andric 10360b57cec5SDimitry Andric class ConstructorMemcpyizer : public FieldMemcpyizer { 10370b57cec5SDimitry Andric private: 10380b57cec5SDimitry Andric /// Get source argument for copy constructor. Returns null if not a copy 10390b57cec5SDimitry Andric /// constructor. 10400b57cec5SDimitry Andric static const VarDecl *getTrivialCopySource(CodeGenFunction &CGF, 10410b57cec5SDimitry Andric const CXXConstructorDecl *CD, 10420b57cec5SDimitry Andric FunctionArgList &Args) { 10430b57cec5SDimitry Andric if (CD->isCopyOrMoveConstructor() && CD->isDefaulted()) 10440b57cec5SDimitry Andric return Args[CGF.CGM.getCXXABI().getSrcArgforCopyCtor(CD, Args)]; 10450b57cec5SDimitry Andric return nullptr; 10460b57cec5SDimitry Andric } 10470b57cec5SDimitry Andric 10480b57cec5SDimitry Andric // Returns true if a CXXCtorInitializer represents a member initialization 10490b57cec5SDimitry Andric // that can be rolled into a memcpy. 10500b57cec5SDimitry Andric bool isMemberInitMemcpyable(CXXCtorInitializer *MemberInit) const { 10510b57cec5SDimitry Andric if (!MemcpyableCtor) 10520b57cec5SDimitry Andric return false; 10530b57cec5SDimitry Andric FieldDecl *Field = MemberInit->getMember(); 10540b57cec5SDimitry Andric assert(Field && "No field for member init."); 10550b57cec5SDimitry Andric QualType FieldType = Field->getType(); 10560b57cec5SDimitry Andric CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit()); 10570b57cec5SDimitry Andric 10580b57cec5SDimitry Andric // Bail out on non-memcpyable, not-trivially-copyable members. 10590b57cec5SDimitry Andric if (!(CE && isMemcpyEquivalentSpecialMember(CE->getConstructor())) && 10600b57cec5SDimitry Andric !(FieldType.isTriviallyCopyableType(CGF.getContext()) || 10610b57cec5SDimitry Andric FieldType->isReferenceType())) 10620b57cec5SDimitry Andric return false; 10630b57cec5SDimitry Andric 10640b57cec5SDimitry Andric // Bail out on volatile fields. 10650b57cec5SDimitry Andric if (!isMemcpyableField(Field)) 10660b57cec5SDimitry Andric return false; 10670b57cec5SDimitry Andric 10680b57cec5SDimitry Andric // Otherwise we're good. 10690b57cec5SDimitry Andric return true; 10700b57cec5SDimitry Andric } 10710b57cec5SDimitry Andric 10720b57cec5SDimitry Andric public: 10730b57cec5SDimitry Andric ConstructorMemcpyizer(CodeGenFunction &CGF, const CXXConstructorDecl *CD, 10740b57cec5SDimitry Andric FunctionArgList &Args) 10750b57cec5SDimitry Andric : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CGF, CD, Args)), 10760b57cec5SDimitry Andric ConstructorDecl(CD), 10770b57cec5SDimitry Andric MemcpyableCtor(CD->isDefaulted() && 10780b57cec5SDimitry Andric CD->isCopyOrMoveConstructor() && 10790b57cec5SDimitry Andric CGF.getLangOpts().getGC() == LangOptions::NonGC), 10800b57cec5SDimitry Andric Args(Args) { } 10810b57cec5SDimitry Andric 10820b57cec5SDimitry Andric void addMemberInitializer(CXXCtorInitializer *MemberInit) { 10830b57cec5SDimitry Andric if (isMemberInitMemcpyable(MemberInit)) { 10840b57cec5SDimitry Andric AggregatedInits.push_back(MemberInit); 10850b57cec5SDimitry Andric addMemcpyableField(MemberInit->getMember()); 10860b57cec5SDimitry Andric } else { 10870b57cec5SDimitry Andric emitAggregatedInits(); 10880b57cec5SDimitry Andric EmitMemberInitializer(CGF, ConstructorDecl->getParent(), MemberInit, 10890b57cec5SDimitry Andric ConstructorDecl, Args); 10900b57cec5SDimitry Andric } 10910b57cec5SDimitry Andric } 10920b57cec5SDimitry Andric 10930b57cec5SDimitry Andric void emitAggregatedInits() { 10940b57cec5SDimitry Andric if (AggregatedInits.size() <= 1) { 10950b57cec5SDimitry Andric // This memcpy is too small to be worthwhile. Fall back on default 10960b57cec5SDimitry Andric // codegen. 10970b57cec5SDimitry Andric if (!AggregatedInits.empty()) { 10980b57cec5SDimitry Andric CopyingValueRepresentation CVR(CGF); 10990b57cec5SDimitry Andric EmitMemberInitializer(CGF, ConstructorDecl->getParent(), 11000b57cec5SDimitry Andric AggregatedInits[0], ConstructorDecl, Args); 11010b57cec5SDimitry Andric AggregatedInits.clear(); 11020b57cec5SDimitry Andric } 11030b57cec5SDimitry Andric reset(); 11040b57cec5SDimitry Andric return; 11050b57cec5SDimitry Andric } 11060b57cec5SDimitry Andric 11070b57cec5SDimitry Andric pushEHDestructors(); 11080b57cec5SDimitry Andric emitMemcpy(); 11090b57cec5SDimitry Andric AggregatedInits.clear(); 11100b57cec5SDimitry Andric } 11110b57cec5SDimitry Andric 11120b57cec5SDimitry Andric void pushEHDestructors() { 11130b57cec5SDimitry Andric Address ThisPtr = CGF.LoadCXXThisAddress(); 11140b57cec5SDimitry Andric QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl); 11150b57cec5SDimitry Andric LValue LHS = CGF.MakeAddrLValue(ThisPtr, RecordTy); 11160b57cec5SDimitry Andric 11170b57cec5SDimitry Andric for (unsigned i = 0; i < AggregatedInits.size(); ++i) { 11180b57cec5SDimitry Andric CXXCtorInitializer *MemberInit = AggregatedInits[i]; 11190b57cec5SDimitry Andric QualType FieldType = MemberInit->getAnyMember()->getType(); 11200b57cec5SDimitry Andric QualType::DestructionKind dtorKind = FieldType.isDestructedType(); 11210b57cec5SDimitry Andric if (!CGF.needsEHCleanup(dtorKind)) 11220b57cec5SDimitry Andric continue; 11230b57cec5SDimitry Andric LValue FieldLHS = LHS; 11240b57cec5SDimitry Andric EmitLValueForAnyFieldInitialization(CGF, MemberInit, FieldLHS); 1125480093f4SDimitry Andric CGF.pushEHDestroy(dtorKind, FieldLHS.getAddress(CGF), FieldType); 11260b57cec5SDimitry Andric } 11270b57cec5SDimitry Andric } 11280b57cec5SDimitry Andric 11290b57cec5SDimitry Andric void finish() { 11300b57cec5SDimitry Andric emitAggregatedInits(); 11310b57cec5SDimitry Andric } 11320b57cec5SDimitry Andric 11330b57cec5SDimitry Andric private: 11340b57cec5SDimitry Andric const CXXConstructorDecl *ConstructorDecl; 11350b57cec5SDimitry Andric bool MemcpyableCtor; 11360b57cec5SDimitry Andric FunctionArgList &Args; 11370b57cec5SDimitry Andric SmallVector<CXXCtorInitializer*, 16> AggregatedInits; 11380b57cec5SDimitry Andric }; 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andric class AssignmentMemcpyizer : public FieldMemcpyizer { 11410b57cec5SDimitry Andric private: 11420b57cec5SDimitry Andric // Returns the memcpyable field copied by the given statement, if one 11430b57cec5SDimitry Andric // exists. Otherwise returns null. 11440b57cec5SDimitry Andric FieldDecl *getMemcpyableField(Stmt *S) { 11450b57cec5SDimitry Andric if (!AssignmentsMemcpyable) 11460b57cec5SDimitry Andric return nullptr; 11470b57cec5SDimitry Andric if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) { 11480b57cec5SDimitry Andric // Recognise trivial assignments. 11490b57cec5SDimitry Andric if (BO->getOpcode() != BO_Assign) 11500b57cec5SDimitry Andric return nullptr; 11510b57cec5SDimitry Andric MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS()); 11520b57cec5SDimitry Andric if (!ME) 11530b57cec5SDimitry Andric return nullptr; 11540b57cec5SDimitry Andric FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl()); 11550b57cec5SDimitry Andric if (!Field || !isMemcpyableField(Field)) 11560b57cec5SDimitry Andric return nullptr; 11570b57cec5SDimitry Andric Stmt *RHS = BO->getRHS(); 11580b57cec5SDimitry Andric if (ImplicitCastExpr *EC = dyn_cast<ImplicitCastExpr>(RHS)) 11590b57cec5SDimitry Andric RHS = EC->getSubExpr(); 11600b57cec5SDimitry Andric if (!RHS) 11610b57cec5SDimitry Andric return nullptr; 11620b57cec5SDimitry Andric if (MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) { 11630b57cec5SDimitry Andric if (ME2->getMemberDecl() == Field) 11640b57cec5SDimitry Andric return Field; 11650b57cec5SDimitry Andric } 11660b57cec5SDimitry Andric return nullptr; 11670b57cec5SDimitry Andric } else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) { 11680b57cec5SDimitry Andric CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl()); 11690b57cec5SDimitry Andric if (!(MD && isMemcpyEquivalentSpecialMember(MD))) 11700b57cec5SDimitry Andric return nullptr; 11710b57cec5SDimitry Andric MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument()); 11720b57cec5SDimitry Andric if (!IOA) 11730b57cec5SDimitry Andric return nullptr; 11740b57cec5SDimitry Andric FieldDecl *Field = dyn_cast<FieldDecl>(IOA->getMemberDecl()); 11750b57cec5SDimitry Andric if (!Field || !isMemcpyableField(Field)) 11760b57cec5SDimitry Andric return nullptr; 11770b57cec5SDimitry Andric MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0)); 11780b57cec5SDimitry Andric if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->getMemberDecl())) 11790b57cec5SDimitry Andric return nullptr; 11800b57cec5SDimitry Andric return Field; 11810b57cec5SDimitry Andric } else if (CallExpr *CE = dyn_cast<CallExpr>(S)) { 11820b57cec5SDimitry Andric FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl()); 11830b57cec5SDimitry Andric if (!FD || FD->getBuiltinID() != Builtin::BI__builtin_memcpy) 11840b57cec5SDimitry Andric return nullptr; 11850b57cec5SDimitry Andric Expr *DstPtr = CE->getArg(0); 11860b57cec5SDimitry Andric if (ImplicitCastExpr *DC = dyn_cast<ImplicitCastExpr>(DstPtr)) 11870b57cec5SDimitry Andric DstPtr = DC->getSubExpr(); 11880b57cec5SDimitry Andric UnaryOperator *DUO = dyn_cast<UnaryOperator>(DstPtr); 11890b57cec5SDimitry Andric if (!DUO || DUO->getOpcode() != UO_AddrOf) 11900b57cec5SDimitry Andric return nullptr; 11910b57cec5SDimitry Andric MemberExpr *ME = dyn_cast<MemberExpr>(DUO->getSubExpr()); 11920b57cec5SDimitry Andric if (!ME) 11930b57cec5SDimitry Andric return nullptr; 11940b57cec5SDimitry Andric FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl()); 11950b57cec5SDimitry Andric if (!Field || !isMemcpyableField(Field)) 11960b57cec5SDimitry Andric return nullptr; 11970b57cec5SDimitry Andric Expr *SrcPtr = CE->getArg(1); 11980b57cec5SDimitry Andric if (ImplicitCastExpr *SC = dyn_cast<ImplicitCastExpr>(SrcPtr)) 11990b57cec5SDimitry Andric SrcPtr = SC->getSubExpr(); 12000b57cec5SDimitry Andric UnaryOperator *SUO = dyn_cast<UnaryOperator>(SrcPtr); 12010b57cec5SDimitry Andric if (!SUO || SUO->getOpcode() != UO_AddrOf) 12020b57cec5SDimitry Andric return nullptr; 12030b57cec5SDimitry Andric MemberExpr *ME2 = dyn_cast<MemberExpr>(SUO->getSubExpr()); 12040b57cec5SDimitry Andric if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->getMemberDecl())) 12050b57cec5SDimitry Andric return nullptr; 12060b57cec5SDimitry Andric return Field; 12070b57cec5SDimitry Andric } 12080b57cec5SDimitry Andric 12090b57cec5SDimitry Andric return nullptr; 12100b57cec5SDimitry Andric } 12110b57cec5SDimitry Andric 12120b57cec5SDimitry Andric bool AssignmentsMemcpyable; 12130b57cec5SDimitry Andric SmallVector<Stmt*, 16> AggregatedStmts; 12140b57cec5SDimitry Andric 12150b57cec5SDimitry Andric public: 12160b57cec5SDimitry Andric AssignmentMemcpyizer(CodeGenFunction &CGF, const CXXMethodDecl *AD, 12170b57cec5SDimitry Andric FunctionArgList &Args) 12180b57cec5SDimitry Andric : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]), 12190b57cec5SDimitry Andric AssignmentsMemcpyable(CGF.getLangOpts().getGC() == LangOptions::NonGC) { 12200b57cec5SDimitry Andric assert(Args.size() == 2); 12210b57cec5SDimitry Andric } 12220b57cec5SDimitry Andric 12230b57cec5SDimitry Andric void emitAssignment(Stmt *S) { 12240b57cec5SDimitry Andric FieldDecl *F = getMemcpyableField(S); 12250b57cec5SDimitry Andric if (F) { 12260b57cec5SDimitry Andric addMemcpyableField(F); 12270b57cec5SDimitry Andric AggregatedStmts.push_back(S); 12280b57cec5SDimitry Andric } else { 12290b57cec5SDimitry Andric emitAggregatedStmts(); 12300b57cec5SDimitry Andric CGF.EmitStmt(S); 12310b57cec5SDimitry Andric } 12320b57cec5SDimitry Andric } 12330b57cec5SDimitry Andric 12340b57cec5SDimitry Andric void emitAggregatedStmts() { 12350b57cec5SDimitry Andric if (AggregatedStmts.size() <= 1) { 12360b57cec5SDimitry Andric if (!AggregatedStmts.empty()) { 12370b57cec5SDimitry Andric CopyingValueRepresentation CVR(CGF); 12380b57cec5SDimitry Andric CGF.EmitStmt(AggregatedStmts[0]); 12390b57cec5SDimitry Andric } 12400b57cec5SDimitry Andric reset(); 12410b57cec5SDimitry Andric } 12420b57cec5SDimitry Andric 12430b57cec5SDimitry Andric emitMemcpy(); 12440b57cec5SDimitry Andric AggregatedStmts.clear(); 12450b57cec5SDimitry Andric } 12460b57cec5SDimitry Andric 12470b57cec5SDimitry Andric void finish() { 12480b57cec5SDimitry Andric emitAggregatedStmts(); 12490b57cec5SDimitry Andric } 12500b57cec5SDimitry Andric }; 12510b57cec5SDimitry Andric } // end anonymous namespace 12520b57cec5SDimitry Andric 12530b57cec5SDimitry Andric static bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit) { 12540b57cec5SDimitry Andric const Type *BaseType = BaseInit->getBaseClass(); 12550b57cec5SDimitry Andric const auto *BaseClassDecl = 1256a7dea167SDimitry Andric cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl()); 12570b57cec5SDimitry Andric return BaseClassDecl->isDynamicClass(); 12580b57cec5SDimitry Andric } 12590b57cec5SDimitry Andric 12600b57cec5SDimitry Andric /// EmitCtorPrologue - This routine generates necessary code to initialize 12610b57cec5SDimitry Andric /// base classes and non-static data members belonging to this constructor. 12620b57cec5SDimitry Andric void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, 12630b57cec5SDimitry Andric CXXCtorType CtorType, 12640b57cec5SDimitry Andric FunctionArgList &Args) { 12650b57cec5SDimitry Andric if (CD->isDelegatingConstructor()) 12660b57cec5SDimitry Andric return EmitDelegatingCXXConstructorCall(CD, Args); 12670b57cec5SDimitry Andric 12680b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = CD->getParent(); 12690b57cec5SDimitry Andric 12700b57cec5SDimitry Andric CXXConstructorDecl::init_const_iterator B = CD->init_begin(), 12710b57cec5SDimitry Andric E = CD->init_end(); 12720b57cec5SDimitry Andric 12730b57cec5SDimitry Andric // Virtual base initializers first, if any. They aren't needed if: 12740b57cec5SDimitry Andric // - This is a base ctor variant 12750b57cec5SDimitry Andric // - There are no vbases 12760b57cec5SDimitry Andric // - The class is abstract, so a complete object of it cannot be constructed 12770b57cec5SDimitry Andric // 12780b57cec5SDimitry Andric // The check for an abstract class is necessary because sema may not have 12790b57cec5SDimitry Andric // marked virtual base destructors referenced. 12800b57cec5SDimitry Andric bool ConstructVBases = CtorType != Ctor_Base && 12810b57cec5SDimitry Andric ClassDecl->getNumVBases() != 0 && 12820b57cec5SDimitry Andric !ClassDecl->isAbstract(); 12830b57cec5SDimitry Andric 12840b57cec5SDimitry Andric // In the Microsoft C++ ABI, there are no constructor variants. Instead, the 12850b57cec5SDimitry Andric // constructor of a class with virtual bases takes an additional parameter to 12860b57cec5SDimitry Andric // conditionally construct the virtual bases. Emit that check here. 12870b57cec5SDimitry Andric llvm::BasicBlock *BaseCtorContinueBB = nullptr; 12880b57cec5SDimitry Andric if (ConstructVBases && 12890b57cec5SDimitry Andric !CGM.getTarget().getCXXABI().hasConstructorVariants()) { 12900b57cec5SDimitry Andric BaseCtorContinueBB = 12910b57cec5SDimitry Andric CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this, ClassDecl); 12920b57cec5SDimitry Andric assert(BaseCtorContinueBB); 12930b57cec5SDimitry Andric } 12940b57cec5SDimitry Andric 12950b57cec5SDimitry Andric for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) { 12960b57cec5SDimitry Andric if (!ConstructVBases) 12970b57cec5SDimitry Andric continue; 12985f757f3fSDimitry Andric SaveAndRestore ThisRAII(CXXThisValue); 12990b57cec5SDimitry Andric if (CGM.getCodeGenOpts().StrictVTablePointers && 13000b57cec5SDimitry Andric CGM.getCodeGenOpts().OptimizationLevel > 0 && 13010b57cec5SDimitry Andric isInitializerOfDynamicClass(*B)) 13020b57cec5SDimitry Andric CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); 13030b57cec5SDimitry Andric EmitBaseInitializer(*this, ClassDecl, *B); 13040b57cec5SDimitry Andric } 13050b57cec5SDimitry Andric 13060b57cec5SDimitry Andric if (BaseCtorContinueBB) { 13070b57cec5SDimitry Andric // Complete object handler should continue to the remaining initializers. 13080b57cec5SDimitry Andric Builder.CreateBr(BaseCtorContinueBB); 13090b57cec5SDimitry Andric EmitBlock(BaseCtorContinueBB); 13100b57cec5SDimitry Andric } 13110b57cec5SDimitry Andric 13120b57cec5SDimitry Andric // Then, non-virtual base initializers. 13130b57cec5SDimitry Andric for (; B != E && (*B)->isBaseInitializer(); B++) { 13140b57cec5SDimitry Andric assert(!(*B)->isBaseVirtual()); 13155f757f3fSDimitry Andric SaveAndRestore ThisRAII(CXXThisValue); 13160b57cec5SDimitry Andric if (CGM.getCodeGenOpts().StrictVTablePointers && 13170b57cec5SDimitry Andric CGM.getCodeGenOpts().OptimizationLevel > 0 && 13180b57cec5SDimitry Andric isInitializerOfDynamicClass(*B)) 13190b57cec5SDimitry Andric CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); 13200b57cec5SDimitry Andric EmitBaseInitializer(*this, ClassDecl, *B); 13210b57cec5SDimitry Andric } 13220b57cec5SDimitry Andric 13230b57cec5SDimitry Andric InitializeVTablePointers(ClassDecl); 13240b57cec5SDimitry Andric 13250b57cec5SDimitry Andric // And finally, initialize class members. 13260b57cec5SDimitry Andric FieldConstructionScope FCS(*this, LoadCXXThisAddress()); 13270b57cec5SDimitry Andric ConstructorMemcpyizer CM(*this, CD, Args); 13280b57cec5SDimitry Andric for (; B != E; B++) { 13290b57cec5SDimitry Andric CXXCtorInitializer *Member = (*B); 13300b57cec5SDimitry Andric assert(!Member->isBaseInitializer()); 13310b57cec5SDimitry Andric assert(Member->isAnyMemberInitializer() && 13320b57cec5SDimitry Andric "Delegating initializer on non-delegating constructor"); 13330b57cec5SDimitry Andric CM.addMemberInitializer(Member); 13340b57cec5SDimitry Andric } 13350b57cec5SDimitry Andric CM.finish(); 13360b57cec5SDimitry Andric } 13370b57cec5SDimitry Andric 13380b57cec5SDimitry Andric static bool 13390b57cec5SDimitry Andric FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field); 13400b57cec5SDimitry Andric 13410b57cec5SDimitry Andric static bool 13420b57cec5SDimitry Andric HasTrivialDestructorBody(ASTContext &Context, 13430b57cec5SDimitry Andric const CXXRecordDecl *BaseClassDecl, 13440b57cec5SDimitry Andric const CXXRecordDecl *MostDerivedClassDecl) 13450b57cec5SDimitry Andric { 13460b57cec5SDimitry Andric // If the destructor is trivial we don't have to check anything else. 13470b57cec5SDimitry Andric if (BaseClassDecl->hasTrivialDestructor()) 13480b57cec5SDimitry Andric return true; 13490b57cec5SDimitry Andric 13500b57cec5SDimitry Andric if (!BaseClassDecl->getDestructor()->hasTrivialBody()) 13510b57cec5SDimitry Andric return false; 13520b57cec5SDimitry Andric 13530b57cec5SDimitry Andric // Check fields. 13540b57cec5SDimitry Andric for (const auto *Field : BaseClassDecl->fields()) 13550b57cec5SDimitry Andric if (!FieldHasTrivialDestructorBody(Context, Field)) 13560b57cec5SDimitry Andric return false; 13570b57cec5SDimitry Andric 13580b57cec5SDimitry Andric // Check non-virtual bases. 13590b57cec5SDimitry Andric for (const auto &I : BaseClassDecl->bases()) { 13600b57cec5SDimitry Andric if (I.isVirtual()) 13610b57cec5SDimitry Andric continue; 13620b57cec5SDimitry Andric 13630b57cec5SDimitry Andric const CXXRecordDecl *NonVirtualBase = 13640b57cec5SDimitry Andric cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 13650b57cec5SDimitry Andric if (!HasTrivialDestructorBody(Context, NonVirtualBase, 13660b57cec5SDimitry Andric MostDerivedClassDecl)) 13670b57cec5SDimitry Andric return false; 13680b57cec5SDimitry Andric } 13690b57cec5SDimitry Andric 13700b57cec5SDimitry Andric if (BaseClassDecl == MostDerivedClassDecl) { 13710b57cec5SDimitry Andric // Check virtual bases. 13720b57cec5SDimitry Andric for (const auto &I : BaseClassDecl->vbases()) { 13730b57cec5SDimitry Andric const CXXRecordDecl *VirtualBase = 13740b57cec5SDimitry Andric cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 13750b57cec5SDimitry Andric if (!HasTrivialDestructorBody(Context, VirtualBase, 13760b57cec5SDimitry Andric MostDerivedClassDecl)) 13770b57cec5SDimitry Andric return false; 13780b57cec5SDimitry Andric } 13790b57cec5SDimitry Andric } 13800b57cec5SDimitry Andric 13810b57cec5SDimitry Andric return true; 13820b57cec5SDimitry Andric } 13830b57cec5SDimitry Andric 13840b57cec5SDimitry Andric static bool 13850b57cec5SDimitry Andric FieldHasTrivialDestructorBody(ASTContext &Context, 13860b57cec5SDimitry Andric const FieldDecl *Field) 13870b57cec5SDimitry Andric { 13880b57cec5SDimitry Andric QualType FieldBaseElementType = Context.getBaseElementType(Field->getType()); 13890b57cec5SDimitry Andric 13900b57cec5SDimitry Andric const RecordType *RT = FieldBaseElementType->getAs<RecordType>(); 13910b57cec5SDimitry Andric if (!RT) 13920b57cec5SDimitry Andric return true; 13930b57cec5SDimitry Andric 13940b57cec5SDimitry Andric CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl()); 13950b57cec5SDimitry Andric 13960b57cec5SDimitry Andric // The destructor for an implicit anonymous union member is never invoked. 13970b57cec5SDimitry Andric if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion()) 13980b57cec5SDimitry Andric return false; 13990b57cec5SDimitry Andric 14000b57cec5SDimitry Andric return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl); 14010b57cec5SDimitry Andric } 14020b57cec5SDimitry Andric 14030b57cec5SDimitry Andric /// CanSkipVTablePointerInitialization - Check whether we need to initialize 14040b57cec5SDimitry Andric /// any vtable pointers before calling this destructor. 14050b57cec5SDimitry Andric static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF, 14060b57cec5SDimitry Andric const CXXDestructorDecl *Dtor) { 14070b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = Dtor->getParent(); 14080b57cec5SDimitry Andric if (!ClassDecl->isDynamicClass()) 14090b57cec5SDimitry Andric return true; 14100b57cec5SDimitry Andric 1411349cc55cSDimitry Andric // For a final class, the vtable pointer is known to already point to the 1412349cc55cSDimitry Andric // class's vtable. 1413349cc55cSDimitry Andric if (ClassDecl->isEffectivelyFinal()) 1414349cc55cSDimitry Andric return true; 1415349cc55cSDimitry Andric 14160b57cec5SDimitry Andric if (!Dtor->hasTrivialBody()) 14170b57cec5SDimitry Andric return false; 14180b57cec5SDimitry Andric 14190b57cec5SDimitry Andric // Check the fields. 14200b57cec5SDimitry Andric for (const auto *Field : ClassDecl->fields()) 14210b57cec5SDimitry Andric if (!FieldHasTrivialDestructorBody(CGF.getContext(), Field)) 14220b57cec5SDimitry Andric return false; 14230b57cec5SDimitry Andric 14240b57cec5SDimitry Andric return true; 14250b57cec5SDimitry Andric } 14260b57cec5SDimitry Andric 14270b57cec5SDimitry Andric /// EmitDestructorBody - Emits the body of the current destructor. 14280b57cec5SDimitry Andric void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { 14290b57cec5SDimitry Andric const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl()); 14300b57cec5SDimitry Andric CXXDtorType DtorType = CurGD.getDtorType(); 14310b57cec5SDimitry Andric 14320b57cec5SDimitry Andric // For an abstract class, non-base destructors are never used (and can't 14330b57cec5SDimitry Andric // be emitted in general, because vbase dtors may not have been validated 14340b57cec5SDimitry Andric // by Sema), but the Itanium ABI doesn't make them optional and Clang may 14350b57cec5SDimitry Andric // in fact emit references to them from other compilations, so emit them 14360b57cec5SDimitry Andric // as functions containing a trap instruction. 14370b57cec5SDimitry Andric if (DtorType != Dtor_Base && Dtor->getParent()->isAbstract()) { 14380b57cec5SDimitry Andric llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap); 14390b57cec5SDimitry Andric TrapCall->setDoesNotReturn(); 14400b57cec5SDimitry Andric TrapCall->setDoesNotThrow(); 14410b57cec5SDimitry Andric Builder.CreateUnreachable(); 14420b57cec5SDimitry Andric Builder.ClearInsertionPoint(); 14430b57cec5SDimitry Andric return; 14440b57cec5SDimitry Andric } 14450b57cec5SDimitry Andric 14460b57cec5SDimitry Andric Stmt *Body = Dtor->getBody(); 14470b57cec5SDimitry Andric if (Body) 14480b57cec5SDimitry Andric incrementProfileCounter(Body); 14490b57cec5SDimitry Andric 14500b57cec5SDimitry Andric // The call to operator delete in a deleting destructor happens 14510b57cec5SDimitry Andric // outside of the function-try-block, which means it's always 14520b57cec5SDimitry Andric // possible to delegate the destructor body to the complete 14530b57cec5SDimitry Andric // destructor. Do so. 14540b57cec5SDimitry Andric if (DtorType == Dtor_Deleting) { 14550b57cec5SDimitry Andric RunCleanupsScope DtorEpilogue(*this); 14560b57cec5SDimitry Andric EnterDtorCleanups(Dtor, Dtor_Deleting); 14570b57cec5SDimitry Andric if (HaveInsertPoint()) { 14585f757f3fSDimitry Andric QualType ThisTy = Dtor->getFunctionObjectParameterType(); 14590b57cec5SDimitry Andric EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false, 14600b57cec5SDimitry Andric /*Delegating=*/false, LoadCXXThisAddress(), ThisTy); 14610b57cec5SDimitry Andric } 14620b57cec5SDimitry Andric return; 14630b57cec5SDimitry Andric } 14640b57cec5SDimitry Andric 14650b57cec5SDimitry Andric // If the body is a function-try-block, enter the try before 14660b57cec5SDimitry Andric // anything else. 14670b57cec5SDimitry Andric bool isTryBody = (Body && isa<CXXTryStmt>(Body)); 14680b57cec5SDimitry Andric if (isTryBody) 14690b57cec5SDimitry Andric EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true); 14700b57cec5SDimitry Andric EmitAsanPrologueOrEpilogue(false); 14710b57cec5SDimitry Andric 14720b57cec5SDimitry Andric // Enter the epilogue cleanups. 14730b57cec5SDimitry Andric RunCleanupsScope DtorEpilogue(*this); 14740b57cec5SDimitry Andric 14750b57cec5SDimitry Andric // If this is the complete variant, just invoke the base variant; 14760b57cec5SDimitry Andric // the epilogue will destruct the virtual bases. But we can't do 14770b57cec5SDimitry Andric // this optimization if the body is a function-try-block, because 14780b57cec5SDimitry Andric // we'd introduce *two* handler blocks. In the Microsoft ABI, we 14790b57cec5SDimitry Andric // always delegate because we might not have a definition in this TU. 14800b57cec5SDimitry Andric switch (DtorType) { 14810b57cec5SDimitry Andric case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT"); 14820b57cec5SDimitry Andric case Dtor_Deleting: llvm_unreachable("already handled deleting case"); 14830b57cec5SDimitry Andric 14840b57cec5SDimitry Andric case Dtor_Complete: 14850b57cec5SDimitry Andric assert((Body || getTarget().getCXXABI().isMicrosoft()) && 14860b57cec5SDimitry Andric "can't emit a dtor without a body for non-Microsoft ABIs"); 14870b57cec5SDimitry Andric 14880b57cec5SDimitry Andric // Enter the cleanup scopes for virtual bases. 14890b57cec5SDimitry Andric EnterDtorCleanups(Dtor, Dtor_Complete); 14900b57cec5SDimitry Andric 14910b57cec5SDimitry Andric if (!isTryBody) { 14925f757f3fSDimitry Andric QualType ThisTy = Dtor->getFunctionObjectParameterType(); 14930b57cec5SDimitry Andric EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false, 14940b57cec5SDimitry Andric /*Delegating=*/false, LoadCXXThisAddress(), ThisTy); 14950b57cec5SDimitry Andric break; 14960b57cec5SDimitry Andric } 14970b57cec5SDimitry Andric 14980b57cec5SDimitry Andric // Fallthrough: act like we're in the base variant. 1499bdd1243dSDimitry Andric [[fallthrough]]; 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andric case Dtor_Base: 15020b57cec5SDimitry Andric assert(Body); 15030b57cec5SDimitry Andric 15040b57cec5SDimitry Andric // Enter the cleanup scopes for fields and non-virtual bases. 15050b57cec5SDimitry Andric EnterDtorCleanups(Dtor, Dtor_Base); 15060b57cec5SDimitry Andric 15070b57cec5SDimitry Andric // Initialize the vtable pointers before entering the body. 15080b57cec5SDimitry Andric if (!CanSkipVTablePointerInitialization(*this, Dtor)) { 15090b57cec5SDimitry Andric // Insert the llvm.launder.invariant.group intrinsic before initializing 15100b57cec5SDimitry Andric // the vptrs to cancel any previous assumptions we might have made. 15110b57cec5SDimitry Andric if (CGM.getCodeGenOpts().StrictVTablePointers && 15120b57cec5SDimitry Andric CGM.getCodeGenOpts().OptimizationLevel > 0) 15130b57cec5SDimitry Andric CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); 15140b57cec5SDimitry Andric InitializeVTablePointers(Dtor->getParent()); 15150b57cec5SDimitry Andric } 15160b57cec5SDimitry Andric 15170b57cec5SDimitry Andric if (isTryBody) 15180b57cec5SDimitry Andric EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock()); 15190b57cec5SDimitry Andric else if (Body) 15200b57cec5SDimitry Andric EmitStmt(Body); 15210b57cec5SDimitry Andric else { 15220b57cec5SDimitry Andric assert(Dtor->isImplicit() && "bodyless dtor not implicit"); 15230b57cec5SDimitry Andric // nothing to do besides what's in the epilogue 15240b57cec5SDimitry Andric } 15250b57cec5SDimitry Andric // -fapple-kext must inline any call to this dtor into 15260b57cec5SDimitry Andric // the caller's body. 15270b57cec5SDimitry Andric if (getLangOpts().AppleKext) 15280b57cec5SDimitry Andric CurFn->addFnAttr(llvm::Attribute::AlwaysInline); 15290b57cec5SDimitry Andric 15300b57cec5SDimitry Andric break; 15310b57cec5SDimitry Andric } 15320b57cec5SDimitry Andric 15330b57cec5SDimitry Andric // Jump out through the epilogue cleanups. 15340b57cec5SDimitry Andric DtorEpilogue.ForceCleanup(); 15350b57cec5SDimitry Andric 15360b57cec5SDimitry Andric // Exit the try if applicable. 15370b57cec5SDimitry Andric if (isTryBody) 15380b57cec5SDimitry Andric ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true); 15390b57cec5SDimitry Andric } 15400b57cec5SDimitry Andric 15410b57cec5SDimitry Andric void CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args) { 15420b57cec5SDimitry Andric const CXXMethodDecl *AssignOp = cast<CXXMethodDecl>(CurGD.getDecl()); 15430b57cec5SDimitry Andric const Stmt *RootS = AssignOp->getBody(); 15440b57cec5SDimitry Andric assert(isa<CompoundStmt>(RootS) && 15450b57cec5SDimitry Andric "Body of an implicit assignment operator should be compound stmt."); 15460b57cec5SDimitry Andric const CompoundStmt *RootCS = cast<CompoundStmt>(RootS); 15470b57cec5SDimitry Andric 15480b57cec5SDimitry Andric LexicalScope Scope(*this, RootCS->getSourceRange()); 15490b57cec5SDimitry Andric 15500b57cec5SDimitry Andric incrementProfileCounter(RootCS); 15510b57cec5SDimitry Andric AssignmentMemcpyizer AM(*this, AssignOp, Args); 15520b57cec5SDimitry Andric for (auto *I : RootCS->body()) 15530b57cec5SDimitry Andric AM.emitAssignment(I); 15540b57cec5SDimitry Andric AM.finish(); 15550b57cec5SDimitry Andric } 15560b57cec5SDimitry Andric 15570b57cec5SDimitry Andric namespace { 15580b57cec5SDimitry Andric llvm::Value *LoadThisForDtorDelete(CodeGenFunction &CGF, 15590b57cec5SDimitry Andric const CXXDestructorDecl *DD) { 15600b57cec5SDimitry Andric if (Expr *ThisArg = DD->getOperatorDeleteThisArg()) 15610b57cec5SDimitry Andric return CGF.EmitScalarExpr(ThisArg); 15620b57cec5SDimitry Andric return CGF.LoadCXXThis(); 15630b57cec5SDimitry Andric } 15640b57cec5SDimitry Andric 15650b57cec5SDimitry Andric /// Call the operator delete associated with the current destructor. 15660b57cec5SDimitry Andric struct CallDtorDelete final : EHScopeStack::Cleanup { 15670b57cec5SDimitry Andric CallDtorDelete() {} 15680b57cec5SDimitry Andric 15690b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 15700b57cec5SDimitry Andric const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 15710b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = Dtor->getParent(); 15720b57cec5SDimitry Andric CGF.EmitDeleteCall(Dtor->getOperatorDelete(), 15730b57cec5SDimitry Andric LoadThisForDtorDelete(CGF, Dtor), 15740b57cec5SDimitry Andric CGF.getContext().getTagDeclType(ClassDecl)); 15750b57cec5SDimitry Andric } 15760b57cec5SDimitry Andric }; 15770b57cec5SDimitry Andric 15780b57cec5SDimitry Andric void EmitConditionalDtorDeleteCall(CodeGenFunction &CGF, 15790b57cec5SDimitry Andric llvm::Value *ShouldDeleteCondition, 15800b57cec5SDimitry Andric bool ReturnAfterDelete) { 15810b57cec5SDimitry Andric llvm::BasicBlock *callDeleteBB = CGF.createBasicBlock("dtor.call_delete"); 15820b57cec5SDimitry Andric llvm::BasicBlock *continueBB = CGF.createBasicBlock("dtor.continue"); 15830b57cec5SDimitry Andric llvm::Value *ShouldCallDelete 15840b57cec5SDimitry Andric = CGF.Builder.CreateIsNull(ShouldDeleteCondition); 15850b57cec5SDimitry Andric CGF.Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB); 15860b57cec5SDimitry Andric 15870b57cec5SDimitry Andric CGF.EmitBlock(callDeleteBB); 15880b57cec5SDimitry Andric const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl); 15890b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = Dtor->getParent(); 15900b57cec5SDimitry Andric CGF.EmitDeleteCall(Dtor->getOperatorDelete(), 15910b57cec5SDimitry Andric LoadThisForDtorDelete(CGF, Dtor), 15920b57cec5SDimitry Andric CGF.getContext().getTagDeclType(ClassDecl)); 15930b57cec5SDimitry Andric assert(Dtor->getOperatorDelete()->isDestroyingOperatorDelete() == 15940b57cec5SDimitry Andric ReturnAfterDelete && 15950b57cec5SDimitry Andric "unexpected value for ReturnAfterDelete"); 15960b57cec5SDimitry Andric if (ReturnAfterDelete) 15970b57cec5SDimitry Andric CGF.EmitBranchThroughCleanup(CGF.ReturnBlock); 15980b57cec5SDimitry Andric else 15990b57cec5SDimitry Andric CGF.Builder.CreateBr(continueBB); 16000b57cec5SDimitry Andric 16010b57cec5SDimitry Andric CGF.EmitBlock(continueBB); 16020b57cec5SDimitry Andric } 16030b57cec5SDimitry Andric 16040b57cec5SDimitry Andric struct CallDtorDeleteConditional final : EHScopeStack::Cleanup { 16050b57cec5SDimitry Andric llvm::Value *ShouldDeleteCondition; 16060b57cec5SDimitry Andric 16070b57cec5SDimitry Andric public: 16080b57cec5SDimitry Andric CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition) 16090b57cec5SDimitry Andric : ShouldDeleteCondition(ShouldDeleteCondition) { 16100b57cec5SDimitry Andric assert(ShouldDeleteCondition != nullptr); 16110b57cec5SDimitry Andric } 16120b57cec5SDimitry Andric 16130b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 16140b57cec5SDimitry Andric EmitConditionalDtorDeleteCall(CGF, ShouldDeleteCondition, 16150b57cec5SDimitry Andric /*ReturnAfterDelete*/false); 16160b57cec5SDimitry Andric } 16170b57cec5SDimitry Andric }; 16180b57cec5SDimitry Andric 16190b57cec5SDimitry Andric class DestroyField final : public EHScopeStack::Cleanup { 16200b57cec5SDimitry Andric const FieldDecl *field; 16210b57cec5SDimitry Andric CodeGenFunction::Destroyer *destroyer; 16220b57cec5SDimitry Andric bool useEHCleanupForArray; 16230b57cec5SDimitry Andric 16240b57cec5SDimitry Andric public: 16250b57cec5SDimitry Andric DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer, 16260b57cec5SDimitry Andric bool useEHCleanupForArray) 16270b57cec5SDimitry Andric : field(field), destroyer(destroyer), 16280b57cec5SDimitry Andric useEHCleanupForArray(useEHCleanupForArray) {} 16290b57cec5SDimitry Andric 16300b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 16310b57cec5SDimitry Andric // Find the address of the field. 16320b57cec5SDimitry Andric Address thisValue = CGF.LoadCXXThisAddress(); 16330b57cec5SDimitry Andric QualType RecordTy = CGF.getContext().getTagDeclType(field->getParent()); 16340b57cec5SDimitry Andric LValue ThisLV = CGF.MakeAddrLValue(thisValue, RecordTy); 16350b57cec5SDimitry Andric LValue LV = CGF.EmitLValueForField(ThisLV, field); 16360b57cec5SDimitry Andric assert(LV.isSimple()); 16370b57cec5SDimitry Andric 1638480093f4SDimitry Andric CGF.emitDestroy(LV.getAddress(CGF), field->getType(), destroyer, 16390b57cec5SDimitry Andric flags.isForNormalCleanup() && useEHCleanupForArray); 16400b57cec5SDimitry Andric } 16410b57cec5SDimitry Andric }; 16420b57cec5SDimitry Andric 1643bdd1243dSDimitry Andric class DeclAsInlineDebugLocation { 1644bdd1243dSDimitry Andric CGDebugInfo *DI; 1645bdd1243dSDimitry Andric llvm::MDNode *InlinedAt; 1646bdd1243dSDimitry Andric std::optional<ApplyDebugLocation> Location; 1647bdd1243dSDimitry Andric 1648bdd1243dSDimitry Andric public: 1649bdd1243dSDimitry Andric DeclAsInlineDebugLocation(CodeGenFunction &CGF, const NamedDecl &Decl) 1650bdd1243dSDimitry Andric : DI(CGF.getDebugInfo()) { 1651bdd1243dSDimitry Andric if (!DI) 1652bdd1243dSDimitry Andric return; 1653bdd1243dSDimitry Andric InlinedAt = DI->getInlinedAt(); 1654bdd1243dSDimitry Andric DI->setInlinedAt(CGF.Builder.getCurrentDebugLocation()); 1655bdd1243dSDimitry Andric Location.emplace(CGF, Decl.getLocation()); 1656bdd1243dSDimitry Andric } 1657bdd1243dSDimitry Andric 1658bdd1243dSDimitry Andric ~DeclAsInlineDebugLocation() { 1659bdd1243dSDimitry Andric if (!DI) 1660bdd1243dSDimitry Andric return; 1661bdd1243dSDimitry Andric Location.reset(); 1662bdd1243dSDimitry Andric DI->setInlinedAt(InlinedAt); 1663bdd1243dSDimitry Andric } 1664bdd1243dSDimitry Andric }; 1665bdd1243dSDimitry Andric 1666bdd1243dSDimitry Andric static void EmitSanitizerDtorCallback( 1667bdd1243dSDimitry Andric CodeGenFunction &CGF, StringRef Name, llvm::Value *Ptr, 1668bdd1243dSDimitry Andric std::optional<CharUnits::QuantityType> PoisonSize = {}) { 16690b57cec5SDimitry Andric CodeGenFunction::SanitizerScope SanScope(&CGF); 16700b57cec5SDimitry Andric // Pass in void pointer and size of region as arguments to runtime 16710b57cec5SDimitry Andric // function 16725f757f3fSDimitry Andric SmallVector<llvm::Value *, 2> Args = {Ptr}; 1673bdd1243dSDimitry Andric SmallVector<llvm::Type *, 2> ArgTypes = {CGF.VoidPtrTy}; 16740b57cec5SDimitry Andric 1675bdd1243dSDimitry Andric if (PoisonSize.has_value()) { 1676bdd1243dSDimitry Andric Args.emplace_back(llvm::ConstantInt::get(CGF.SizeTy, *PoisonSize)); 1677bdd1243dSDimitry Andric ArgTypes.emplace_back(CGF.SizeTy); 1678bdd1243dSDimitry Andric } 16790b57cec5SDimitry Andric 16800b57cec5SDimitry Andric llvm::FunctionType *FnType = 16810b57cec5SDimitry Andric llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false); 1682bdd1243dSDimitry Andric llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction(FnType, Name); 1683bdd1243dSDimitry Andric 16840b57cec5SDimitry Andric CGF.EmitNounwindRuntimeCall(Fn, Args); 16850b57cec5SDimitry Andric } 16860b57cec5SDimitry Andric 1687bdd1243dSDimitry Andric static void 1688bdd1243dSDimitry Andric EmitSanitizerDtorFieldsCallback(CodeGenFunction &CGF, llvm::Value *Ptr, 1689bdd1243dSDimitry Andric CharUnits::QuantityType PoisonSize) { 1690bdd1243dSDimitry Andric EmitSanitizerDtorCallback(CGF, "__sanitizer_dtor_callback_fields", Ptr, 1691bdd1243dSDimitry Andric PoisonSize); 1692bdd1243dSDimitry Andric } 1693bdd1243dSDimitry Andric 169481ad6265SDimitry Andric /// Poison base class with a trivial destructor. 169581ad6265SDimitry Andric struct SanitizeDtorTrivialBase final : EHScopeStack::Cleanup { 169681ad6265SDimitry Andric const CXXRecordDecl *BaseClass; 169781ad6265SDimitry Andric bool BaseIsVirtual; 169881ad6265SDimitry Andric SanitizeDtorTrivialBase(const CXXRecordDecl *Base, bool BaseIsVirtual) 169981ad6265SDimitry Andric : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {} 170081ad6265SDimitry Andric 170181ad6265SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 170281ad6265SDimitry Andric const CXXRecordDecl *DerivedClass = 170381ad6265SDimitry Andric cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent(); 170481ad6265SDimitry Andric 170581ad6265SDimitry Andric Address Addr = CGF.GetAddressOfDirectBaseInCompleteClass( 170681ad6265SDimitry Andric CGF.LoadCXXThisAddress(), DerivedClass, BaseClass, BaseIsVirtual); 170781ad6265SDimitry Andric 170881ad6265SDimitry Andric const ASTRecordLayout &BaseLayout = 170981ad6265SDimitry Andric CGF.getContext().getASTRecordLayout(BaseClass); 171081ad6265SDimitry Andric CharUnits BaseSize = BaseLayout.getSize(); 171181ad6265SDimitry Andric 171281ad6265SDimitry Andric if (!BaseSize.isPositive()) 171381ad6265SDimitry Andric return; 171481ad6265SDimitry Andric 1715bdd1243dSDimitry Andric // Use the base class declaration location as inline DebugLocation. All 1716bdd1243dSDimitry Andric // fields of the class are destroyed. 1717bdd1243dSDimitry Andric DeclAsInlineDebugLocation InlineHere(CGF, *BaseClass); 1718bdd1243dSDimitry Andric EmitSanitizerDtorFieldsCallback(CGF, Addr.getPointer(), 1719bdd1243dSDimitry Andric BaseSize.getQuantity()); 172081ad6265SDimitry Andric 172181ad6265SDimitry Andric // Prevent the current stack frame from disappearing from the stack trace. 172281ad6265SDimitry Andric CGF.CurFn->addFnAttr("disable-tail-calls", "true"); 172381ad6265SDimitry Andric } 172481ad6265SDimitry Andric }; 172581ad6265SDimitry Andric 172681ad6265SDimitry Andric class SanitizeDtorFieldRange final : public EHScopeStack::Cleanup { 17270b57cec5SDimitry Andric const CXXDestructorDecl *Dtor; 172881ad6265SDimitry Andric unsigned StartIndex; 172981ad6265SDimitry Andric unsigned EndIndex; 17300b57cec5SDimitry Andric 17310b57cec5SDimitry Andric public: 173281ad6265SDimitry Andric SanitizeDtorFieldRange(const CXXDestructorDecl *Dtor, unsigned StartIndex, 173381ad6265SDimitry Andric unsigned EndIndex) 173481ad6265SDimitry Andric : Dtor(Dtor), StartIndex(StartIndex), EndIndex(EndIndex) {} 17350b57cec5SDimitry Andric 17360b57cec5SDimitry Andric // Generate function call for handling object poisoning. 17370b57cec5SDimitry Andric // Disables tail call elimination, to prevent the current stack frame 17380b57cec5SDimitry Andric // from disappearing from the stack trace. 17390b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 174081ad6265SDimitry Andric const ASTContext &Context = CGF.getContext(); 17410b57cec5SDimitry Andric const ASTRecordLayout &Layout = 17420b57cec5SDimitry Andric Context.getASTRecordLayout(Dtor->getParent()); 17430b57cec5SDimitry Andric 174481ad6265SDimitry Andric // It's a first trivial field so it should be at the begining of a char, 1745e8d8bef9SDimitry Andric // still round up start offset just in case. 174681ad6265SDimitry Andric CharUnits PoisonStart = Context.toCharUnitsFromBits( 174781ad6265SDimitry Andric Layout.getFieldOffset(StartIndex) + Context.getCharWidth() - 1); 1748e8d8bef9SDimitry Andric llvm::ConstantInt *OffsetSizePtr = 1749e8d8bef9SDimitry Andric llvm::ConstantInt::get(CGF.SizeTy, PoisonStart.getQuantity()); 17500b57cec5SDimitry Andric 17515f757f3fSDimitry Andric llvm::Value *OffsetPtr = 17525f757f3fSDimitry Andric CGF.Builder.CreateGEP(CGF.Int8Ty, CGF.LoadCXXThis(), OffsetSizePtr); 17530b57cec5SDimitry Andric 1754e8d8bef9SDimitry Andric CharUnits PoisonEnd; 175581ad6265SDimitry Andric if (EndIndex >= Layout.getFieldCount()) { 1756e8d8bef9SDimitry Andric PoisonEnd = Layout.getNonVirtualSize(); 17570b57cec5SDimitry Andric } else { 1758e8d8bef9SDimitry Andric PoisonEnd = 175981ad6265SDimitry Andric Context.toCharUnitsFromBits(Layout.getFieldOffset(EndIndex)); 17600b57cec5SDimitry Andric } 1761e8d8bef9SDimitry Andric CharUnits PoisonSize = PoisonEnd - PoisonStart; 1762e8d8bef9SDimitry Andric if (!PoisonSize.isPositive()) 17630b57cec5SDimitry Andric return; 17640b57cec5SDimitry Andric 1765bdd1243dSDimitry Andric // Use the top field declaration location as inline DebugLocation. 1766bdd1243dSDimitry Andric DeclAsInlineDebugLocation InlineHere( 1767bdd1243dSDimitry Andric CGF, **std::next(Dtor->getParent()->field_begin(), StartIndex)); 1768bdd1243dSDimitry Andric EmitSanitizerDtorFieldsCallback(CGF, OffsetPtr, PoisonSize.getQuantity()); 176981ad6265SDimitry Andric 177081ad6265SDimitry Andric // Prevent the current stack frame from disappearing from the stack trace. 177181ad6265SDimitry Andric CGF.CurFn->addFnAttr("disable-tail-calls", "true"); 17720b57cec5SDimitry Andric } 17730b57cec5SDimitry Andric }; 17740b57cec5SDimitry Andric 17750b57cec5SDimitry Andric class SanitizeDtorVTable final : public EHScopeStack::Cleanup { 17760b57cec5SDimitry Andric const CXXDestructorDecl *Dtor; 17770b57cec5SDimitry Andric 17780b57cec5SDimitry Andric public: 17790b57cec5SDimitry Andric SanitizeDtorVTable(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {} 17800b57cec5SDimitry Andric 17810b57cec5SDimitry Andric // Generate function call for handling vtable pointer poisoning. 17820b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 17830b57cec5SDimitry Andric assert(Dtor->getParent()->isDynamicClass()); 17840b57cec5SDimitry Andric (void)Dtor; 17850b57cec5SDimitry Andric // Poison vtable and vtable ptr if they exist for this class. 17860b57cec5SDimitry Andric llvm::Value *VTablePtr = CGF.LoadCXXThis(); 17870b57cec5SDimitry Andric 17880b57cec5SDimitry Andric // Pass in void pointer and size of region as arguments to runtime 17890b57cec5SDimitry Andric // function 1790bdd1243dSDimitry Andric EmitSanitizerDtorCallback(CGF, "__sanitizer_dtor_callback_vptr", 1791bdd1243dSDimitry Andric VTablePtr); 17920b57cec5SDimitry Andric } 17930b57cec5SDimitry Andric }; 179481ad6265SDimitry Andric 179581ad6265SDimitry Andric class SanitizeDtorCleanupBuilder { 179681ad6265SDimitry Andric ASTContext &Context; 179781ad6265SDimitry Andric EHScopeStack &EHStack; 179881ad6265SDimitry Andric const CXXDestructorDecl *DD; 1799bdd1243dSDimitry Andric std::optional<unsigned> StartIndex; 180081ad6265SDimitry Andric 180181ad6265SDimitry Andric public: 180281ad6265SDimitry Andric SanitizeDtorCleanupBuilder(ASTContext &Context, EHScopeStack &EHStack, 180381ad6265SDimitry Andric const CXXDestructorDecl *DD) 1804bdd1243dSDimitry Andric : Context(Context), EHStack(EHStack), DD(DD), StartIndex(std::nullopt) {} 180581ad6265SDimitry Andric void PushCleanupForField(const FieldDecl *Field) { 180681ad6265SDimitry Andric if (Field->isZeroSize(Context)) 180781ad6265SDimitry Andric return; 180881ad6265SDimitry Andric unsigned FieldIndex = Field->getFieldIndex(); 180981ad6265SDimitry Andric if (FieldHasTrivialDestructorBody(Context, Field)) { 181081ad6265SDimitry Andric if (!StartIndex) 181181ad6265SDimitry Andric StartIndex = FieldIndex; 181281ad6265SDimitry Andric } else if (StartIndex) { 1813bdd1243dSDimitry Andric EHStack.pushCleanup<SanitizeDtorFieldRange>(NormalAndEHCleanup, DD, 1814bdd1243dSDimitry Andric *StartIndex, FieldIndex); 1815bdd1243dSDimitry Andric StartIndex = std::nullopt; 181681ad6265SDimitry Andric } 181781ad6265SDimitry Andric } 181881ad6265SDimitry Andric void End() { 181981ad6265SDimitry Andric if (StartIndex) 182081ad6265SDimitry Andric EHStack.pushCleanup<SanitizeDtorFieldRange>(NormalAndEHCleanup, DD, 1821bdd1243dSDimitry Andric *StartIndex, -1); 182281ad6265SDimitry Andric } 182381ad6265SDimitry Andric }; 18240b57cec5SDimitry Andric } // end anonymous namespace 18250b57cec5SDimitry Andric 18260b57cec5SDimitry Andric /// Emit all code that comes at the end of class's 18270b57cec5SDimitry Andric /// destructor. This is to call destructors on members and base classes 18280b57cec5SDimitry Andric /// in reverse order of their construction. 18290b57cec5SDimitry Andric /// 18300b57cec5SDimitry Andric /// For a deleting destructor, this also handles the case where a destroying 18310b57cec5SDimitry Andric /// operator delete completely overrides the definition. 18320b57cec5SDimitry Andric void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD, 18330b57cec5SDimitry Andric CXXDtorType DtorType) { 18340b57cec5SDimitry Andric assert((!DD->isTrivial() || DD->hasAttr<DLLExportAttr>()) && 18350b57cec5SDimitry Andric "Should not emit dtor epilogue for non-exported trivial dtor!"); 18360b57cec5SDimitry Andric 18370b57cec5SDimitry Andric // The deleting-destructor phase just needs to call the appropriate 18380b57cec5SDimitry Andric // operator delete that Sema picked up. 18390b57cec5SDimitry Andric if (DtorType == Dtor_Deleting) { 18400b57cec5SDimitry Andric assert(DD->getOperatorDelete() && 18410b57cec5SDimitry Andric "operator delete missing - EnterDtorCleanups"); 18420b57cec5SDimitry Andric if (CXXStructorImplicitParamValue) { 18430b57cec5SDimitry Andric // If there is an implicit param to the deleting dtor, it's a boolean 18440b57cec5SDimitry Andric // telling whether this is a deleting destructor. 18450b57cec5SDimitry Andric if (DD->getOperatorDelete()->isDestroyingOperatorDelete()) 18460b57cec5SDimitry Andric EmitConditionalDtorDeleteCall(*this, CXXStructorImplicitParamValue, 18470b57cec5SDimitry Andric /*ReturnAfterDelete*/true); 18480b57cec5SDimitry Andric else 18490b57cec5SDimitry Andric EHStack.pushCleanup<CallDtorDeleteConditional>( 18500b57cec5SDimitry Andric NormalAndEHCleanup, CXXStructorImplicitParamValue); 18510b57cec5SDimitry Andric } else { 18520b57cec5SDimitry Andric if (DD->getOperatorDelete()->isDestroyingOperatorDelete()) { 18530b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = DD->getParent(); 18540b57cec5SDimitry Andric EmitDeleteCall(DD->getOperatorDelete(), 18550b57cec5SDimitry Andric LoadThisForDtorDelete(*this, DD), 18560b57cec5SDimitry Andric getContext().getTagDeclType(ClassDecl)); 18570b57cec5SDimitry Andric EmitBranchThroughCleanup(ReturnBlock); 18580b57cec5SDimitry Andric } else { 18590b57cec5SDimitry Andric EHStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup); 18600b57cec5SDimitry Andric } 18610b57cec5SDimitry Andric } 18620b57cec5SDimitry Andric return; 18630b57cec5SDimitry Andric } 18640b57cec5SDimitry Andric 18650b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = DD->getParent(); 18660b57cec5SDimitry Andric 18670b57cec5SDimitry Andric // Unions have no bases and do not call field destructors. 18680b57cec5SDimitry Andric if (ClassDecl->isUnion()) 18690b57cec5SDimitry Andric return; 18700b57cec5SDimitry Andric 18710b57cec5SDimitry Andric // The complete-destructor phase just destructs all the virtual bases. 18720b57cec5SDimitry Andric if (DtorType == Dtor_Complete) { 18730b57cec5SDimitry Andric // Poison the vtable pointer such that access after the base 18740b57cec5SDimitry Andric // and member destructors are invoked is invalid. 18750b57cec5SDimitry Andric if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor && 18760b57cec5SDimitry Andric SanOpts.has(SanitizerKind::Memory) && ClassDecl->getNumVBases() && 18770b57cec5SDimitry Andric ClassDecl->isPolymorphic()) 18780b57cec5SDimitry Andric EHStack.pushCleanup<SanitizeDtorVTable>(NormalAndEHCleanup, DD); 18790b57cec5SDimitry Andric 18800b57cec5SDimitry Andric // We push them in the forward order so that they'll be popped in 18810b57cec5SDimitry Andric // the reverse order. 18820b57cec5SDimitry Andric for (const auto &Base : ClassDecl->vbases()) { 1883a7dea167SDimitry Andric auto *BaseClassDecl = 1884a7dea167SDimitry Andric cast<CXXRecordDecl>(Base.getType()->castAs<RecordType>()->getDecl()); 18850b57cec5SDimitry Andric 188681ad6265SDimitry Andric if (BaseClassDecl->hasTrivialDestructor()) { 188781ad6265SDimitry Andric // Under SanitizeMemoryUseAfterDtor, poison the trivial base class 188881ad6265SDimitry Andric // memory. For non-trival base classes the same is done in the class 188981ad6265SDimitry Andric // destructor. 189081ad6265SDimitry Andric if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor && 189181ad6265SDimitry Andric SanOpts.has(SanitizerKind::Memory) && !BaseClassDecl->isEmpty()) 189281ad6265SDimitry Andric EHStack.pushCleanup<SanitizeDtorTrivialBase>(NormalAndEHCleanup, 18930b57cec5SDimitry Andric BaseClassDecl, 18940b57cec5SDimitry Andric /*BaseIsVirtual*/ true); 189581ad6265SDimitry Andric } else { 189681ad6265SDimitry Andric EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, BaseClassDecl, 189781ad6265SDimitry Andric /*BaseIsVirtual*/ true); 189881ad6265SDimitry Andric } 18990b57cec5SDimitry Andric } 19000b57cec5SDimitry Andric 19010b57cec5SDimitry Andric return; 19020b57cec5SDimitry Andric } 19030b57cec5SDimitry Andric 19040b57cec5SDimitry Andric assert(DtorType == Dtor_Base); 19050b57cec5SDimitry Andric // Poison the vtable pointer if it has no virtual bases, but inherits 19060b57cec5SDimitry Andric // virtual functions. 19070b57cec5SDimitry Andric if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor && 19080b57cec5SDimitry Andric SanOpts.has(SanitizerKind::Memory) && !ClassDecl->getNumVBases() && 19090b57cec5SDimitry Andric ClassDecl->isPolymorphic()) 19100b57cec5SDimitry Andric EHStack.pushCleanup<SanitizeDtorVTable>(NormalAndEHCleanup, DD); 19110b57cec5SDimitry Andric 19120b57cec5SDimitry Andric // Destroy non-virtual bases. 19130b57cec5SDimitry Andric for (const auto &Base : ClassDecl->bases()) { 19140b57cec5SDimitry Andric // Ignore virtual bases. 19150b57cec5SDimitry Andric if (Base.isVirtual()) 19160b57cec5SDimitry Andric continue; 19170b57cec5SDimitry Andric 19180b57cec5SDimitry Andric CXXRecordDecl *BaseClassDecl = Base.getType()->getAsCXXRecordDecl(); 19190b57cec5SDimitry Andric 192081ad6265SDimitry Andric if (BaseClassDecl->hasTrivialDestructor()) { 192181ad6265SDimitry Andric if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor && 192281ad6265SDimitry Andric SanOpts.has(SanitizerKind::Memory) && !BaseClassDecl->isEmpty()) 192381ad6265SDimitry Andric EHStack.pushCleanup<SanitizeDtorTrivialBase>(NormalAndEHCleanup, 19240b57cec5SDimitry Andric BaseClassDecl, 19250b57cec5SDimitry Andric /*BaseIsVirtual*/ false); 192681ad6265SDimitry Andric } else { 192781ad6265SDimitry Andric EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, BaseClassDecl, 192881ad6265SDimitry Andric /*BaseIsVirtual*/ false); 192981ad6265SDimitry Andric } 19300b57cec5SDimitry Andric } 19310b57cec5SDimitry Andric 19320b57cec5SDimitry Andric // Poison fields such that access after their destructors are 19330b57cec5SDimitry Andric // invoked, and before the base class destructor runs, is invalid. 193481ad6265SDimitry Andric bool SanitizeFields = CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor && 193581ad6265SDimitry Andric SanOpts.has(SanitizerKind::Memory); 193681ad6265SDimitry Andric SanitizeDtorCleanupBuilder SanitizeBuilder(getContext(), EHStack, DD); 19370b57cec5SDimitry Andric 19380b57cec5SDimitry Andric // Destroy direct fields. 19390b57cec5SDimitry Andric for (const auto *Field : ClassDecl->fields()) { 194081ad6265SDimitry Andric if (SanitizeFields) 194181ad6265SDimitry Andric SanitizeBuilder.PushCleanupForField(Field); 194281ad6265SDimitry Andric 19430b57cec5SDimitry Andric QualType type = Field->getType(); 19440b57cec5SDimitry Andric QualType::DestructionKind dtorKind = type.isDestructedType(); 194581ad6265SDimitry Andric if (!dtorKind) 194681ad6265SDimitry Andric continue; 19470b57cec5SDimitry Andric 19480b57cec5SDimitry Andric // Anonymous union members do not have their destructors called. 19490b57cec5SDimitry Andric const RecordType *RT = type->getAsUnionType(); 195081ad6265SDimitry Andric if (RT && RT->getDecl()->isAnonymousStructOrUnion()) 195181ad6265SDimitry Andric continue; 19520b57cec5SDimitry Andric 19530b57cec5SDimitry Andric CleanupKind cleanupKind = getCleanupKind(dtorKind); 195481ad6265SDimitry Andric EHStack.pushCleanup<DestroyField>( 195581ad6265SDimitry Andric cleanupKind, Field, getDestroyer(dtorKind), cleanupKind & EHCleanup); 19560b57cec5SDimitry Andric } 195781ad6265SDimitry Andric 195881ad6265SDimitry Andric if (SanitizeFields) 195981ad6265SDimitry Andric SanitizeBuilder.End(); 19600b57cec5SDimitry Andric } 19610b57cec5SDimitry Andric 19620b57cec5SDimitry Andric /// EmitCXXAggrConstructorCall - Emit a loop to call a particular 19630b57cec5SDimitry Andric /// constructor for each of several members of an array. 19640b57cec5SDimitry Andric /// 19650b57cec5SDimitry Andric /// \param ctor the constructor to call for each element 19660b57cec5SDimitry Andric /// \param arrayType the type of the array to initialize 19670b57cec5SDimitry Andric /// \param arrayBegin an arrayType* 19680b57cec5SDimitry Andric /// \param zeroInitialize true if each element should be 19690b57cec5SDimitry Andric /// zero-initialized before it is constructed 19700b57cec5SDimitry Andric void CodeGenFunction::EmitCXXAggrConstructorCall( 19710b57cec5SDimitry Andric const CXXConstructorDecl *ctor, const ArrayType *arrayType, 19720b57cec5SDimitry Andric Address arrayBegin, const CXXConstructExpr *E, bool NewPointerIsChecked, 19730b57cec5SDimitry Andric bool zeroInitialize) { 19740b57cec5SDimitry Andric QualType elementType; 19750b57cec5SDimitry Andric llvm::Value *numElements = 19760b57cec5SDimitry Andric emitArrayLength(arrayType, elementType, arrayBegin); 19770b57cec5SDimitry Andric 19780b57cec5SDimitry Andric EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, E, 19790b57cec5SDimitry Andric NewPointerIsChecked, zeroInitialize); 19800b57cec5SDimitry Andric } 19810b57cec5SDimitry Andric 19820b57cec5SDimitry Andric /// EmitCXXAggrConstructorCall - Emit a loop to call a particular 19830b57cec5SDimitry Andric /// constructor for each of several members of an array. 19840b57cec5SDimitry Andric /// 19850b57cec5SDimitry Andric /// \param ctor the constructor to call for each element 19860b57cec5SDimitry Andric /// \param numElements the number of elements in the array; 19870b57cec5SDimitry Andric /// may be zero 19880b57cec5SDimitry Andric /// \param arrayBase a T*, where T is the type constructed by ctor 19890b57cec5SDimitry Andric /// \param zeroInitialize true if each element should be 19900b57cec5SDimitry Andric /// zero-initialized before it is constructed 19910b57cec5SDimitry Andric void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor, 19920b57cec5SDimitry Andric llvm::Value *numElements, 19930b57cec5SDimitry Andric Address arrayBase, 19940b57cec5SDimitry Andric const CXXConstructExpr *E, 19950b57cec5SDimitry Andric bool NewPointerIsChecked, 19960b57cec5SDimitry Andric bool zeroInitialize) { 19970b57cec5SDimitry Andric // It's legal for numElements to be zero. This can happen both 19980b57cec5SDimitry Andric // dynamically, because x can be zero in 'new A[x]', and statically, 19990b57cec5SDimitry Andric // because of GCC extensions that permit zero-length arrays. There 20000b57cec5SDimitry Andric // are probably legitimate places where we could assume that this 20010b57cec5SDimitry Andric // doesn't happen, but it's not clear that it's worth it. 20020b57cec5SDimitry Andric llvm::BranchInst *zeroCheckBranch = nullptr; 20030b57cec5SDimitry Andric 20040b57cec5SDimitry Andric // Optimize for a constant count. 20050b57cec5SDimitry Andric llvm::ConstantInt *constantCount 20060b57cec5SDimitry Andric = dyn_cast<llvm::ConstantInt>(numElements); 20070b57cec5SDimitry Andric if (constantCount) { 20080b57cec5SDimitry Andric // Just skip out if the constant count is zero. 20090b57cec5SDimitry Andric if (constantCount->isZero()) return; 20100b57cec5SDimitry Andric 20110b57cec5SDimitry Andric // Otherwise, emit the check. 20120b57cec5SDimitry Andric } else { 20130b57cec5SDimitry Andric llvm::BasicBlock *loopBB = createBasicBlock("new.ctorloop"); 20140b57cec5SDimitry Andric llvm::Value *iszero = Builder.CreateIsNull(numElements, "isempty"); 20150b57cec5SDimitry Andric zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB); 20160b57cec5SDimitry Andric EmitBlock(loopBB); 20170b57cec5SDimitry Andric } 20180b57cec5SDimitry Andric 20190b57cec5SDimitry Andric // Find the end of the array. 2020fe6060f1SDimitry Andric llvm::Type *elementType = arrayBase.getElementType(); 20210b57cec5SDimitry Andric llvm::Value *arrayBegin = arrayBase.getPointer(); 2022fe6060f1SDimitry Andric llvm::Value *arrayEnd = Builder.CreateInBoundsGEP( 2023fe6060f1SDimitry Andric elementType, arrayBegin, numElements, "arrayctor.end"); 20240b57cec5SDimitry Andric 20250b57cec5SDimitry Andric // Enter the loop, setting up a phi for the current location to initialize. 20260b57cec5SDimitry Andric llvm::BasicBlock *entryBB = Builder.GetInsertBlock(); 20270b57cec5SDimitry Andric llvm::BasicBlock *loopBB = createBasicBlock("arrayctor.loop"); 20280b57cec5SDimitry Andric EmitBlock(loopBB); 20290b57cec5SDimitry Andric llvm::PHINode *cur = Builder.CreatePHI(arrayBegin->getType(), 2, 20300b57cec5SDimitry Andric "arrayctor.cur"); 20310b57cec5SDimitry Andric cur->addIncoming(arrayBegin, entryBB); 20320b57cec5SDimitry Andric 20330b57cec5SDimitry Andric // Inside the loop body, emit the constructor call on the array element. 20340b57cec5SDimitry Andric 20350b57cec5SDimitry Andric // The alignment of the base, adjusted by the size of a single element, 20360b57cec5SDimitry Andric // provides a conservative estimate of the alignment of every element. 20370b57cec5SDimitry Andric // (This assumes we never start tracking offsetted alignments.) 20380b57cec5SDimitry Andric // 20390b57cec5SDimitry Andric // Note that these are complete objects and so we don't need to 20400b57cec5SDimitry Andric // use the non-virtual size or alignment. 20410b57cec5SDimitry Andric QualType type = getContext().getTypeDeclType(ctor->getParent()); 20420b57cec5SDimitry Andric CharUnits eltAlignment = 20430b57cec5SDimitry Andric arrayBase.getAlignment() 20440b57cec5SDimitry Andric .alignmentOfArrayElement(getContext().getTypeSizeInChars(type)); 204504eeddc0SDimitry Andric Address curAddr = Address(cur, elementType, eltAlignment); 20460b57cec5SDimitry Andric 20470b57cec5SDimitry Andric // Zero initialize the storage, if requested. 20480b57cec5SDimitry Andric if (zeroInitialize) 20490b57cec5SDimitry Andric EmitNullInitialization(curAddr, type); 20500b57cec5SDimitry Andric 20510b57cec5SDimitry Andric // C++ [class.temporary]p4: 20520b57cec5SDimitry Andric // There are two contexts in which temporaries are destroyed at a different 20530b57cec5SDimitry Andric // point than the end of the full-expression. The first context is when a 20540b57cec5SDimitry Andric // default constructor is called to initialize an element of an array. 20550b57cec5SDimitry Andric // If the constructor has one or more default arguments, the destruction of 20560b57cec5SDimitry Andric // every temporary created in a default argument expression is sequenced 20570b57cec5SDimitry Andric // before the construction of the next array element, if any. 20580b57cec5SDimitry Andric 20590b57cec5SDimitry Andric { 20600b57cec5SDimitry Andric RunCleanupsScope Scope(*this); 20610b57cec5SDimitry Andric 20620b57cec5SDimitry Andric // Evaluate the constructor and its arguments in a regular 20630b57cec5SDimitry Andric // partial-destroy cleanup. 20640b57cec5SDimitry Andric if (getLangOpts().Exceptions && 20650b57cec5SDimitry Andric !ctor->getParent()->hasTrivialDestructor()) { 20660b57cec5SDimitry Andric Destroyer *destroyer = destroyCXXObject; 20670b57cec5SDimitry Andric pushRegularPartialArrayCleanup(arrayBegin, cur, type, eltAlignment, 20680b57cec5SDimitry Andric *destroyer); 20690b57cec5SDimitry Andric } 20700b57cec5SDimitry Andric auto currAVS = AggValueSlot::forAddr( 20710b57cec5SDimitry Andric curAddr, type.getQualifiers(), AggValueSlot::IsDestructed, 20720b57cec5SDimitry Andric AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, 20730b57cec5SDimitry Andric AggValueSlot::DoesNotOverlap, AggValueSlot::IsNotZeroed, 20740b57cec5SDimitry Andric NewPointerIsChecked ? AggValueSlot::IsSanitizerChecked 20750b57cec5SDimitry Andric : AggValueSlot::IsNotSanitizerChecked); 20760b57cec5SDimitry Andric EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/false, 20770b57cec5SDimitry Andric /*Delegating=*/false, currAVS, E); 20780b57cec5SDimitry Andric } 20790b57cec5SDimitry Andric 20800b57cec5SDimitry Andric // Go to the next element. 2081fe6060f1SDimitry Andric llvm::Value *next = Builder.CreateInBoundsGEP( 2082fe6060f1SDimitry Andric elementType, cur, llvm::ConstantInt::get(SizeTy, 1), "arrayctor.next"); 20830b57cec5SDimitry Andric cur->addIncoming(next, Builder.GetInsertBlock()); 20840b57cec5SDimitry Andric 20850b57cec5SDimitry Andric // Check whether that's the end of the loop. 20860b57cec5SDimitry Andric llvm::Value *done = Builder.CreateICmpEQ(next, arrayEnd, "arrayctor.done"); 20870b57cec5SDimitry Andric llvm::BasicBlock *contBB = createBasicBlock("arrayctor.cont"); 20880b57cec5SDimitry Andric Builder.CreateCondBr(done, contBB, loopBB); 20890b57cec5SDimitry Andric 20900b57cec5SDimitry Andric // Patch the earlier check to skip over the loop. 20910b57cec5SDimitry Andric if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB); 20920b57cec5SDimitry Andric 20930b57cec5SDimitry Andric EmitBlock(contBB); 20940b57cec5SDimitry Andric } 20950b57cec5SDimitry Andric 20960b57cec5SDimitry Andric void CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF, 20970b57cec5SDimitry Andric Address addr, 20980b57cec5SDimitry Andric QualType type) { 20990b57cec5SDimitry Andric const RecordType *rtype = type->castAs<RecordType>(); 21000b57cec5SDimitry Andric const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl()); 21010b57cec5SDimitry Andric const CXXDestructorDecl *dtor = record->getDestructor(); 21020b57cec5SDimitry Andric assert(!dtor->isTrivial()); 21030b57cec5SDimitry Andric CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false, 21040b57cec5SDimitry Andric /*Delegating=*/false, addr, type); 21050b57cec5SDimitry Andric } 21060b57cec5SDimitry Andric 21070b57cec5SDimitry Andric void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 21080b57cec5SDimitry Andric CXXCtorType Type, 21090b57cec5SDimitry Andric bool ForVirtualBase, 21100b57cec5SDimitry Andric bool Delegating, 21110b57cec5SDimitry Andric AggValueSlot ThisAVS, 21120b57cec5SDimitry Andric const CXXConstructExpr *E) { 21130b57cec5SDimitry Andric CallArgList Args; 21140b57cec5SDimitry Andric Address This = ThisAVS.getAddress(); 21150b57cec5SDimitry Andric LangAS SlotAS = ThisAVS.getQualifiers().getAddressSpace(); 21165f757f3fSDimitry Andric LangAS ThisAS = D->getFunctionObjectParameterType().getAddressSpace(); 21170b57cec5SDimitry Andric llvm::Value *ThisPtr = This.getPointer(); 21180b57cec5SDimitry Andric 21190b57cec5SDimitry Andric if (SlotAS != ThisAS) { 21200b57cec5SDimitry Andric unsigned TargetThisAS = getContext().getTargetAddressSpace(ThisAS); 212106c3fb27SDimitry Andric llvm::Type *NewType = 212206c3fb27SDimitry Andric llvm::PointerType::get(getLLVMContext(), TargetThisAS); 21230b57cec5SDimitry Andric ThisPtr = getTargetHooks().performAddrSpaceCast(*this, This.getPointer(), 21240b57cec5SDimitry Andric ThisAS, SlotAS, NewType); 21250b57cec5SDimitry Andric } 21260b57cec5SDimitry Andric 21270b57cec5SDimitry Andric // Push the this ptr. 21280b57cec5SDimitry Andric Args.add(RValue::get(ThisPtr), D->getThisType()); 21290b57cec5SDimitry Andric 21300b57cec5SDimitry Andric // If this is a trivial constructor, emit a memcpy now before we lose 21310b57cec5SDimitry Andric // the alignment information on the argument. 21320b57cec5SDimitry Andric // FIXME: It would be better to preserve alignment information into CallArg. 21330b57cec5SDimitry Andric if (isMemcpyEquivalentSpecialMember(D)) { 21340b57cec5SDimitry Andric assert(E->getNumArgs() == 1 && "unexpected argcount for trivial ctor"); 21350b57cec5SDimitry Andric 21360b57cec5SDimitry Andric const Expr *Arg = E->getArg(0); 21370b57cec5SDimitry Andric LValue Src = EmitLValue(Arg); 21380b57cec5SDimitry Andric QualType DestTy = getContext().getTypeDeclType(D->getParent()); 21390b57cec5SDimitry Andric LValue Dest = MakeAddrLValue(This, DestTy); 21400b57cec5SDimitry Andric EmitAggregateCopyCtor(Dest, Src, ThisAVS.mayOverlap()); 21410b57cec5SDimitry Andric return; 21420b57cec5SDimitry Andric } 21430b57cec5SDimitry Andric 21440b57cec5SDimitry Andric // Add the rest of the user-supplied arguments. 21450b57cec5SDimitry Andric const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>(); 21460b57cec5SDimitry Andric EvaluationOrder Order = E->isListInitialization() 21470b57cec5SDimitry Andric ? EvaluationOrder::ForceLeftToRight 21480b57cec5SDimitry Andric : EvaluationOrder::Default; 21490b57cec5SDimitry Andric EmitCallArgs(Args, FPT, E->arguments(), E->getConstructor(), 21500b57cec5SDimitry Andric /*ParamsToSkip*/ 0, Order); 21510b57cec5SDimitry Andric 21520b57cec5SDimitry Andric EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args, 21530b57cec5SDimitry Andric ThisAVS.mayOverlap(), E->getExprLoc(), 21540b57cec5SDimitry Andric ThisAVS.isSanitizerChecked()); 21550b57cec5SDimitry Andric } 21560b57cec5SDimitry Andric 21570b57cec5SDimitry Andric static bool canEmitDelegateCallArgs(CodeGenFunction &CGF, 21580b57cec5SDimitry Andric const CXXConstructorDecl *Ctor, 21590b57cec5SDimitry Andric CXXCtorType Type, CallArgList &Args) { 21600b57cec5SDimitry Andric // We can't forward a variadic call. 21610b57cec5SDimitry Andric if (Ctor->isVariadic()) 21620b57cec5SDimitry Andric return false; 21630b57cec5SDimitry Andric 21640b57cec5SDimitry Andric if (CGF.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) { 21650b57cec5SDimitry Andric // If the parameters are callee-cleanup, it's not safe to forward. 21660b57cec5SDimitry Andric for (auto *P : Ctor->parameters()) 2167a7dea167SDimitry Andric if (P->needsDestruction(CGF.getContext())) 21680b57cec5SDimitry Andric return false; 21690b57cec5SDimitry Andric 21700b57cec5SDimitry Andric // Likewise if they're inalloca. 21710b57cec5SDimitry Andric const CGFunctionInfo &Info = 21720b57cec5SDimitry Andric CGF.CGM.getTypes().arrangeCXXConstructorCall(Args, Ctor, Type, 0, 0); 21730b57cec5SDimitry Andric if (Info.usesInAlloca()) 21740b57cec5SDimitry Andric return false; 21750b57cec5SDimitry Andric } 21760b57cec5SDimitry Andric 21770b57cec5SDimitry Andric // Anything else should be OK. 21780b57cec5SDimitry Andric return true; 21790b57cec5SDimitry Andric } 21800b57cec5SDimitry Andric 21810b57cec5SDimitry Andric void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, 21820b57cec5SDimitry Andric CXXCtorType Type, 21830b57cec5SDimitry Andric bool ForVirtualBase, 21840b57cec5SDimitry Andric bool Delegating, 21850b57cec5SDimitry Andric Address This, 21860b57cec5SDimitry Andric CallArgList &Args, 21870b57cec5SDimitry Andric AggValueSlot::Overlap_t Overlap, 21880b57cec5SDimitry Andric SourceLocation Loc, 21890b57cec5SDimitry Andric bool NewPointerIsChecked) { 21900b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = D->getParent(); 21910b57cec5SDimitry Andric 21920b57cec5SDimitry Andric if (!NewPointerIsChecked) 21930b57cec5SDimitry Andric EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, Loc, This.getPointer(), 21940b57cec5SDimitry Andric getContext().getRecordType(ClassDecl), CharUnits::Zero()); 21950b57cec5SDimitry Andric 21960b57cec5SDimitry Andric if (D->isTrivial() && D->isDefaultConstructor()) { 21970b57cec5SDimitry Andric assert(Args.size() == 1 && "trivial default ctor with args"); 21980b57cec5SDimitry Andric return; 21990b57cec5SDimitry Andric } 22000b57cec5SDimitry Andric 22010b57cec5SDimitry Andric // If this is a trivial constructor, just emit what's needed. If this is a 22020b57cec5SDimitry Andric // union copy constructor, we must emit a memcpy, because the AST does not 22030b57cec5SDimitry Andric // model that copy. 22040b57cec5SDimitry Andric if (isMemcpyEquivalentSpecialMember(D)) { 22050b57cec5SDimitry Andric assert(Args.size() == 2 && "unexpected argcount for trivial ctor"); 22060b57cec5SDimitry Andric 22070b57cec5SDimitry Andric QualType SrcTy = D->getParamDecl(0)->getType().getNonReferenceType(); 220881ad6265SDimitry Andric Address Src = Address(Args[1].getRValue(*this).getScalarVal(), ConvertTypeForMem(SrcTy), 22095ffd83dbSDimitry Andric CGM.getNaturalTypeAlignment(SrcTy)); 22100b57cec5SDimitry Andric LValue SrcLVal = MakeAddrLValue(Src, SrcTy); 22110b57cec5SDimitry Andric QualType DestTy = getContext().getTypeDeclType(ClassDecl); 22120b57cec5SDimitry Andric LValue DestLVal = MakeAddrLValue(This, DestTy); 22130b57cec5SDimitry Andric EmitAggregateCopyCtor(DestLVal, SrcLVal, Overlap); 22140b57cec5SDimitry Andric return; 22150b57cec5SDimitry Andric } 22160b57cec5SDimitry Andric 22170b57cec5SDimitry Andric bool PassPrototypeArgs = true; 22180b57cec5SDimitry Andric // Check whether we can actually emit the constructor before trying to do so. 22190b57cec5SDimitry Andric if (auto Inherited = D->getInheritedConstructor()) { 22200b57cec5SDimitry Andric PassPrototypeArgs = getTypes().inheritingCtorHasParams(Inherited, Type); 22210b57cec5SDimitry Andric if (PassPrototypeArgs && !canEmitDelegateCallArgs(*this, D, Type, Args)) { 22220b57cec5SDimitry Andric EmitInlinedInheritingCXXConstructorCall(D, Type, ForVirtualBase, 22230b57cec5SDimitry Andric Delegating, Args); 22240b57cec5SDimitry Andric return; 22250b57cec5SDimitry Andric } 22260b57cec5SDimitry Andric } 22270b57cec5SDimitry Andric 22280b57cec5SDimitry Andric // Insert any ABI-specific implicit constructor arguments. 22295ffd83dbSDimitry Andric CGCXXABI::AddedStructorArgCounts ExtraArgs = 22300b57cec5SDimitry Andric CGM.getCXXABI().addImplicitConstructorArgs(*this, D, Type, ForVirtualBase, 22310b57cec5SDimitry Andric Delegating, Args); 22320b57cec5SDimitry Andric 22330b57cec5SDimitry Andric // Emit the call. 22340b57cec5SDimitry Andric llvm::Constant *CalleePtr = CGM.getAddrOfCXXStructor(GlobalDecl(D, Type)); 22350b57cec5SDimitry Andric const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall( 22360b57cec5SDimitry Andric Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs); 22370b57cec5SDimitry Andric CGCallee Callee = CGCallee::forDirect(CalleePtr, GlobalDecl(D, Type)); 2238fe6060f1SDimitry Andric EmitCall(Info, Callee, ReturnValueSlot(), Args, nullptr, false, Loc); 22390b57cec5SDimitry Andric 22400b57cec5SDimitry Andric // Generate vtable assumptions if we're constructing a complete object 22410b57cec5SDimitry Andric // with a vtable. We don't do this for base subobjects for two reasons: 22420b57cec5SDimitry Andric // first, it's incorrect for classes with virtual bases, and second, we're 22430b57cec5SDimitry Andric // about to overwrite the vptrs anyway. 22440b57cec5SDimitry Andric // We also have to make sure if we can refer to vtable: 22450b57cec5SDimitry Andric // - Otherwise we can refer to vtable if it's safe to speculatively emit. 22460b57cec5SDimitry Andric // FIXME: If vtable is used by ctor/dtor, or if vtable is external and we are 22470b57cec5SDimitry Andric // sure that definition of vtable is not hidden, 22480b57cec5SDimitry Andric // then we are always safe to refer to it. 22490b57cec5SDimitry Andric // FIXME: It looks like InstCombine is very inefficient on dealing with 22500b57cec5SDimitry Andric // assumes. Make assumption loads require -fstrict-vtable-pointers temporarily. 22510b57cec5SDimitry Andric if (CGM.getCodeGenOpts().OptimizationLevel > 0 && 22520b57cec5SDimitry Andric ClassDecl->isDynamicClass() && Type != Ctor_Base && 22530b57cec5SDimitry Andric CGM.getCXXABI().canSpeculativelyEmitVTable(ClassDecl) && 22540b57cec5SDimitry Andric CGM.getCodeGenOpts().StrictVTablePointers) 22550b57cec5SDimitry Andric EmitVTableAssumptionLoads(ClassDecl, This); 22560b57cec5SDimitry Andric } 22570b57cec5SDimitry Andric 22580b57cec5SDimitry Andric void CodeGenFunction::EmitInheritedCXXConstructorCall( 22590b57cec5SDimitry Andric const CXXConstructorDecl *D, bool ForVirtualBase, Address This, 22600b57cec5SDimitry Andric bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E) { 22610b57cec5SDimitry Andric CallArgList Args; 22620b57cec5SDimitry Andric CallArg ThisArg(RValue::get(This.getPointer()), D->getThisType()); 22630b57cec5SDimitry Andric 22640b57cec5SDimitry Andric // Forward the parameters. 22650b57cec5SDimitry Andric if (InheritedFromVBase && 22660b57cec5SDimitry Andric CGM.getTarget().getCXXABI().hasConstructorVariants()) { 22670b57cec5SDimitry Andric // Nothing to do; this construction is not responsible for constructing 22680b57cec5SDimitry Andric // the base class containing the inherited constructor. 22690b57cec5SDimitry Andric // FIXME: Can we just pass undef's for the remaining arguments if we don't 22700b57cec5SDimitry Andric // have constructor variants? 22710b57cec5SDimitry Andric Args.push_back(ThisArg); 22720b57cec5SDimitry Andric } else if (!CXXInheritedCtorInitExprArgs.empty()) { 22730b57cec5SDimitry Andric // The inheriting constructor was inlined; just inject its arguments. 22740b57cec5SDimitry Andric assert(CXXInheritedCtorInitExprArgs.size() >= D->getNumParams() && 22750b57cec5SDimitry Andric "wrong number of parameters for inherited constructor call"); 22760b57cec5SDimitry Andric Args = CXXInheritedCtorInitExprArgs; 22770b57cec5SDimitry Andric Args[0] = ThisArg; 22780b57cec5SDimitry Andric } else { 22790b57cec5SDimitry Andric // The inheriting constructor was not inlined. Emit delegating arguments. 22800b57cec5SDimitry Andric Args.push_back(ThisArg); 22810b57cec5SDimitry Andric const auto *OuterCtor = cast<CXXConstructorDecl>(CurCodeDecl); 22820b57cec5SDimitry Andric assert(OuterCtor->getNumParams() == D->getNumParams()); 22830b57cec5SDimitry Andric assert(!OuterCtor->isVariadic() && "should have been inlined"); 22840b57cec5SDimitry Andric 22850b57cec5SDimitry Andric for (const auto *Param : OuterCtor->parameters()) { 22860b57cec5SDimitry Andric assert(getContext().hasSameUnqualifiedType( 22870b57cec5SDimitry Andric OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->getType(), 22880b57cec5SDimitry Andric Param->getType())); 22890b57cec5SDimitry Andric EmitDelegateCallArg(Args, Param, E->getLocation()); 22900b57cec5SDimitry Andric 22910b57cec5SDimitry Andric // Forward __attribute__(pass_object_size). 22920b57cec5SDimitry Andric if (Param->hasAttr<PassObjectSizeAttr>()) { 22930b57cec5SDimitry Andric auto *POSParam = SizeArguments[Param]; 22940b57cec5SDimitry Andric assert(POSParam && "missing pass_object_size value for forwarding"); 22950b57cec5SDimitry Andric EmitDelegateCallArg(Args, POSParam, E->getLocation()); 22960b57cec5SDimitry Andric } 22970b57cec5SDimitry Andric } 22980b57cec5SDimitry Andric } 22990b57cec5SDimitry Andric 23000b57cec5SDimitry Andric EmitCXXConstructorCall(D, Ctor_Base, ForVirtualBase, /*Delegating*/false, 23010b57cec5SDimitry Andric This, Args, AggValueSlot::MayOverlap, 23020b57cec5SDimitry Andric E->getLocation(), /*NewPointerIsChecked*/true); 23030b57cec5SDimitry Andric } 23040b57cec5SDimitry Andric 23050b57cec5SDimitry Andric void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall( 23060b57cec5SDimitry Andric const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase, 23070b57cec5SDimitry Andric bool Delegating, CallArgList &Args) { 23080b57cec5SDimitry Andric GlobalDecl GD(Ctor, CtorType); 23090b57cec5SDimitry Andric InlinedInheritingConstructorScope Scope(*this, GD); 23100b57cec5SDimitry Andric ApplyInlineDebugLocation DebugScope(*this, GD); 23110b57cec5SDimitry Andric RunCleanupsScope RunCleanups(*this); 23120b57cec5SDimitry Andric 23130b57cec5SDimitry Andric // Save the arguments to be passed to the inherited constructor. 23140b57cec5SDimitry Andric CXXInheritedCtorInitExprArgs = Args; 23150b57cec5SDimitry Andric 23160b57cec5SDimitry Andric FunctionArgList Params; 23170b57cec5SDimitry Andric QualType RetType = BuildFunctionArgList(CurGD, Params); 23180b57cec5SDimitry Andric FnRetTy = RetType; 23190b57cec5SDimitry Andric 23200b57cec5SDimitry Andric // Insert any ABI-specific implicit constructor arguments. 23210b57cec5SDimitry Andric CGM.getCXXABI().addImplicitConstructorArgs(*this, Ctor, CtorType, 23220b57cec5SDimitry Andric ForVirtualBase, Delegating, Args); 23230b57cec5SDimitry Andric 23240b57cec5SDimitry Andric // Emit a simplified prolog. We only need to emit the implicit params. 23250b57cec5SDimitry Andric assert(Args.size() >= Params.size() && "too few arguments for call"); 23260b57cec5SDimitry Andric for (unsigned I = 0, N = Args.size(); I != N; ++I) { 23270b57cec5SDimitry Andric if (I < Params.size() && isa<ImplicitParamDecl>(Params[I])) { 23280b57cec5SDimitry Andric const RValue &RV = Args[I].getRValue(*this); 23290b57cec5SDimitry Andric assert(!RV.isComplex() && "complex indirect params not supported"); 23300b57cec5SDimitry Andric ParamValue Val = RV.isScalar() 23310b57cec5SDimitry Andric ? ParamValue::forDirect(RV.getScalarVal()) 23320b57cec5SDimitry Andric : ParamValue::forIndirect(RV.getAggregateAddress()); 23330b57cec5SDimitry Andric EmitParmDecl(*Params[I], Val, I + 1); 23340b57cec5SDimitry Andric } 23350b57cec5SDimitry Andric } 23360b57cec5SDimitry Andric 23370b57cec5SDimitry Andric // Create a return value slot if the ABI implementation wants one. 23380b57cec5SDimitry Andric // FIXME: This is dumb, we should ask the ABI not to try to set the return 23390b57cec5SDimitry Andric // value instead. 23400b57cec5SDimitry Andric if (!RetType->isVoidType()) 23410b57cec5SDimitry Andric ReturnValue = CreateIRTemp(RetType, "retval.inhctor"); 23420b57cec5SDimitry Andric 23430b57cec5SDimitry Andric CGM.getCXXABI().EmitInstanceFunctionProlog(*this); 23440b57cec5SDimitry Andric CXXThisValue = CXXABIThisValue; 23450b57cec5SDimitry Andric 23460b57cec5SDimitry Andric // Directly emit the constructor initializers. 23470b57cec5SDimitry Andric EmitCtorPrologue(Ctor, CtorType, Params); 23480b57cec5SDimitry Andric } 23490b57cec5SDimitry Andric 23500b57cec5SDimitry Andric void CodeGenFunction::EmitVTableAssumptionLoad(const VPtr &Vptr, Address This) { 23510b57cec5SDimitry Andric llvm::Value *VTableGlobal = 23520b57cec5SDimitry Andric CGM.getCXXABI().getVTableAddressPoint(Vptr.Base, Vptr.VTableClass); 23530b57cec5SDimitry Andric if (!VTableGlobal) 23540b57cec5SDimitry Andric return; 23550b57cec5SDimitry Andric 23560b57cec5SDimitry Andric // We can just use the base offset in the complete class. 23570b57cec5SDimitry Andric CharUnits NonVirtualOffset = Vptr.Base.getBaseOffset(); 23580b57cec5SDimitry Andric 23590b57cec5SDimitry Andric if (!NonVirtualOffset.isZero()) 23600b57cec5SDimitry Andric This = 23610b57cec5SDimitry Andric ApplyNonVirtualAndVirtualOffset(*this, This, NonVirtualOffset, nullptr, 23620b57cec5SDimitry Andric Vptr.VTableClass, Vptr.NearestVBase); 23630b57cec5SDimitry Andric 23640b57cec5SDimitry Andric llvm::Value *VPtrValue = 23650b57cec5SDimitry Andric GetVTablePtr(This, VTableGlobal->getType(), Vptr.VTableClass); 23660b57cec5SDimitry Andric llvm::Value *Cmp = 23670b57cec5SDimitry Andric Builder.CreateICmpEQ(VPtrValue, VTableGlobal, "cmp.vtables"); 23680b57cec5SDimitry Andric Builder.CreateAssumption(Cmp); 23690b57cec5SDimitry Andric } 23700b57cec5SDimitry Andric 23710b57cec5SDimitry Andric void CodeGenFunction::EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, 23720b57cec5SDimitry Andric Address This) { 23730b57cec5SDimitry Andric if (CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl)) 23740b57cec5SDimitry Andric for (const VPtr &Vptr : getVTablePointers(ClassDecl)) 23750b57cec5SDimitry Andric EmitVTableAssumptionLoad(Vptr, This); 23760b57cec5SDimitry Andric } 23770b57cec5SDimitry Andric 23780b57cec5SDimitry Andric void 23790b57cec5SDimitry Andric CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, 23800b57cec5SDimitry Andric Address This, Address Src, 23810b57cec5SDimitry Andric const CXXConstructExpr *E) { 23820b57cec5SDimitry Andric const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>(); 23830b57cec5SDimitry Andric 23840b57cec5SDimitry Andric CallArgList Args; 23850b57cec5SDimitry Andric 23860b57cec5SDimitry Andric // Push the this ptr. 23870b57cec5SDimitry Andric Args.add(RValue::get(This.getPointer()), D->getThisType()); 23880b57cec5SDimitry Andric 23890b57cec5SDimitry Andric // Push the src ptr. 23900b57cec5SDimitry Andric QualType QT = *(FPT->param_type_begin()); 23910b57cec5SDimitry Andric llvm::Type *t = CGM.getTypes().ConvertType(QT); 239281ad6265SDimitry Andric llvm::Value *SrcVal = Builder.CreateBitCast(Src.getPointer(), t); 239381ad6265SDimitry Andric Args.add(RValue::get(SrcVal), QT); 23940b57cec5SDimitry Andric 23950b57cec5SDimitry Andric // Skip over first argument (Src). 23960b57cec5SDimitry Andric EmitCallArgs(Args, FPT, drop_begin(E->arguments(), 1), E->getConstructor(), 23970b57cec5SDimitry Andric /*ParamsToSkip*/ 1); 23980b57cec5SDimitry Andric 23990b57cec5SDimitry Andric EmitCXXConstructorCall(D, Ctor_Complete, /*ForVirtualBase*/false, 24000b57cec5SDimitry Andric /*Delegating*/false, This, Args, 24010b57cec5SDimitry Andric AggValueSlot::MayOverlap, E->getExprLoc(), 24020b57cec5SDimitry Andric /*NewPointerIsChecked*/false); 24030b57cec5SDimitry Andric } 24040b57cec5SDimitry Andric 24050b57cec5SDimitry Andric void 24060b57cec5SDimitry Andric CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, 24070b57cec5SDimitry Andric CXXCtorType CtorType, 24080b57cec5SDimitry Andric const FunctionArgList &Args, 24090b57cec5SDimitry Andric SourceLocation Loc) { 24100b57cec5SDimitry Andric CallArgList DelegateArgs; 24110b57cec5SDimitry Andric 24120b57cec5SDimitry Andric FunctionArgList::const_iterator I = Args.begin(), E = Args.end(); 24130b57cec5SDimitry Andric assert(I != E && "no parameters to constructor"); 24140b57cec5SDimitry Andric 24150b57cec5SDimitry Andric // this 24160b57cec5SDimitry Andric Address This = LoadCXXThisAddress(); 24170b57cec5SDimitry Andric DelegateArgs.add(RValue::get(This.getPointer()), (*I)->getType()); 24180b57cec5SDimitry Andric ++I; 24190b57cec5SDimitry Andric 24200b57cec5SDimitry Andric // FIXME: The location of the VTT parameter in the parameter list is 24210b57cec5SDimitry Andric // specific to the Itanium ABI and shouldn't be hardcoded here. 24220b57cec5SDimitry Andric if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) { 24230b57cec5SDimitry Andric assert(I != E && "cannot skip vtt parameter, already done with args"); 24240b57cec5SDimitry Andric assert((*I)->getType()->isPointerType() && 24250b57cec5SDimitry Andric "skipping parameter not of vtt type"); 24260b57cec5SDimitry Andric ++I; 24270b57cec5SDimitry Andric } 24280b57cec5SDimitry Andric 24290b57cec5SDimitry Andric // Explicit arguments. 24300b57cec5SDimitry Andric for (; I != E; ++I) { 24310b57cec5SDimitry Andric const VarDecl *param = *I; 24320b57cec5SDimitry Andric // FIXME: per-argument source location 24330b57cec5SDimitry Andric EmitDelegateCallArg(DelegateArgs, param, Loc); 24340b57cec5SDimitry Andric } 24350b57cec5SDimitry Andric 24360b57cec5SDimitry Andric EmitCXXConstructorCall(Ctor, CtorType, /*ForVirtualBase=*/false, 24370b57cec5SDimitry Andric /*Delegating=*/true, This, DelegateArgs, 24380b57cec5SDimitry Andric AggValueSlot::MayOverlap, Loc, 24390b57cec5SDimitry Andric /*NewPointerIsChecked=*/true); 24400b57cec5SDimitry Andric } 24410b57cec5SDimitry Andric 24420b57cec5SDimitry Andric namespace { 24430b57cec5SDimitry Andric struct CallDelegatingCtorDtor final : EHScopeStack::Cleanup { 24440b57cec5SDimitry Andric const CXXDestructorDecl *Dtor; 24450b57cec5SDimitry Andric Address Addr; 24460b57cec5SDimitry Andric CXXDtorType Type; 24470b57cec5SDimitry Andric 24480b57cec5SDimitry Andric CallDelegatingCtorDtor(const CXXDestructorDecl *D, Address Addr, 24490b57cec5SDimitry Andric CXXDtorType Type) 24500b57cec5SDimitry Andric : Dtor(D), Addr(Addr), Type(Type) {} 24510b57cec5SDimitry Andric 24520b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 24530b57cec5SDimitry Andric // We are calling the destructor from within the constructor. 24540b57cec5SDimitry Andric // Therefore, "this" should have the expected type. 24555f757f3fSDimitry Andric QualType ThisTy = Dtor->getFunctionObjectParameterType(); 24560b57cec5SDimitry Andric CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false, 24570b57cec5SDimitry Andric /*Delegating=*/true, Addr, ThisTy); 24580b57cec5SDimitry Andric } 24590b57cec5SDimitry Andric }; 24600b57cec5SDimitry Andric } // end anonymous namespace 24610b57cec5SDimitry Andric 24620b57cec5SDimitry Andric void 24630b57cec5SDimitry Andric CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, 24640b57cec5SDimitry Andric const FunctionArgList &Args) { 24650b57cec5SDimitry Andric assert(Ctor->isDelegatingConstructor()); 24660b57cec5SDimitry Andric 24670b57cec5SDimitry Andric Address ThisPtr = LoadCXXThisAddress(); 24680b57cec5SDimitry Andric 24690b57cec5SDimitry Andric AggValueSlot AggSlot = 24700b57cec5SDimitry Andric AggValueSlot::forAddr(ThisPtr, Qualifiers(), 24710b57cec5SDimitry Andric AggValueSlot::IsDestructed, 24720b57cec5SDimitry Andric AggValueSlot::DoesNotNeedGCBarriers, 24730b57cec5SDimitry Andric AggValueSlot::IsNotAliased, 24740b57cec5SDimitry Andric AggValueSlot::MayOverlap, 24750b57cec5SDimitry Andric AggValueSlot::IsNotZeroed, 24760b57cec5SDimitry Andric // Checks are made by the code that calls constructor. 24770b57cec5SDimitry Andric AggValueSlot::IsSanitizerChecked); 24780b57cec5SDimitry Andric 24790b57cec5SDimitry Andric EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot); 24800b57cec5SDimitry Andric 24810b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = Ctor->getParent(); 24820b57cec5SDimitry Andric if (CGM.getLangOpts().Exceptions && !ClassDecl->hasTrivialDestructor()) { 24830b57cec5SDimitry Andric CXXDtorType Type = 24840b57cec5SDimitry Andric CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base; 24850b57cec5SDimitry Andric 24860b57cec5SDimitry Andric EHStack.pushCleanup<CallDelegatingCtorDtor>(EHCleanup, 24870b57cec5SDimitry Andric ClassDecl->getDestructor(), 24880b57cec5SDimitry Andric ThisPtr, Type); 24890b57cec5SDimitry Andric } 24900b57cec5SDimitry Andric } 24910b57cec5SDimitry Andric 24920b57cec5SDimitry Andric void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, 24930b57cec5SDimitry Andric CXXDtorType Type, 24940b57cec5SDimitry Andric bool ForVirtualBase, 24950b57cec5SDimitry Andric bool Delegating, Address This, 24960b57cec5SDimitry Andric QualType ThisTy) { 24970b57cec5SDimitry Andric CGM.getCXXABI().EmitDestructorCall(*this, DD, Type, ForVirtualBase, 24980b57cec5SDimitry Andric Delegating, This, ThisTy); 24990b57cec5SDimitry Andric } 25000b57cec5SDimitry Andric 25010b57cec5SDimitry Andric namespace { 25020b57cec5SDimitry Andric struct CallLocalDtor final : EHScopeStack::Cleanup { 25030b57cec5SDimitry Andric const CXXDestructorDecl *Dtor; 25040b57cec5SDimitry Andric Address Addr; 25050b57cec5SDimitry Andric QualType Ty; 25060b57cec5SDimitry Andric 25070b57cec5SDimitry Andric CallLocalDtor(const CXXDestructorDecl *D, Address Addr, QualType Ty) 25080b57cec5SDimitry Andric : Dtor(D), Addr(Addr), Ty(Ty) {} 25090b57cec5SDimitry Andric 25100b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 25110b57cec5SDimitry Andric CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, 25120b57cec5SDimitry Andric /*ForVirtualBase=*/false, 25130b57cec5SDimitry Andric /*Delegating=*/false, Addr, Ty); 25140b57cec5SDimitry Andric } 25150b57cec5SDimitry Andric }; 25160b57cec5SDimitry Andric } // end anonymous namespace 25170b57cec5SDimitry Andric 25180b57cec5SDimitry Andric void CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D, 25190b57cec5SDimitry Andric QualType T, Address Addr) { 25200b57cec5SDimitry Andric EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr, T); 25210b57cec5SDimitry Andric } 25220b57cec5SDimitry Andric 25230b57cec5SDimitry Andric void CodeGenFunction::PushDestructorCleanup(QualType T, Address Addr) { 25240b57cec5SDimitry Andric CXXRecordDecl *ClassDecl = T->getAsCXXRecordDecl(); 25250b57cec5SDimitry Andric if (!ClassDecl) return; 25260b57cec5SDimitry Andric if (ClassDecl->hasTrivialDestructor()) return; 25270b57cec5SDimitry Andric 25280b57cec5SDimitry Andric const CXXDestructorDecl *D = ClassDecl->getDestructor(); 25290b57cec5SDimitry Andric assert(D && D->isUsed() && "destructor not marked as used!"); 25300b57cec5SDimitry Andric PushDestructorCleanup(D, T, Addr); 25310b57cec5SDimitry Andric } 25320b57cec5SDimitry Andric 25330b57cec5SDimitry Andric void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) { 25340b57cec5SDimitry Andric // Compute the address point. 25350b57cec5SDimitry Andric llvm::Value *VTableAddressPoint = 25360b57cec5SDimitry Andric CGM.getCXXABI().getVTableAddressPointInStructor( 25370b57cec5SDimitry Andric *this, Vptr.VTableClass, Vptr.Base, Vptr.NearestVBase); 25380b57cec5SDimitry Andric 25390b57cec5SDimitry Andric if (!VTableAddressPoint) 25400b57cec5SDimitry Andric return; 25410b57cec5SDimitry Andric 25420b57cec5SDimitry Andric // Compute where to store the address point. 25430b57cec5SDimitry Andric llvm::Value *VirtualOffset = nullptr; 25440b57cec5SDimitry Andric CharUnits NonVirtualOffset = CharUnits::Zero(); 25450b57cec5SDimitry Andric 25460b57cec5SDimitry Andric if (CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*this, Vptr)) { 25470b57cec5SDimitry Andric // We need to use the virtual base offset offset because the virtual base 25480b57cec5SDimitry Andric // might have a different offset in the most derived class. 25490b57cec5SDimitry Andric 25500b57cec5SDimitry Andric VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset( 25510b57cec5SDimitry Andric *this, LoadCXXThisAddress(), Vptr.VTableClass, Vptr.NearestVBase); 25520b57cec5SDimitry Andric NonVirtualOffset = Vptr.OffsetFromNearestVBase; 25530b57cec5SDimitry Andric } else { 25540b57cec5SDimitry Andric // We can just use the base offset in the complete class. 25550b57cec5SDimitry Andric NonVirtualOffset = Vptr.Base.getBaseOffset(); 25560b57cec5SDimitry Andric } 25570b57cec5SDimitry Andric 25580b57cec5SDimitry Andric // Apply the offsets. 25590b57cec5SDimitry Andric Address VTableField = LoadCXXThisAddress(); 25600b57cec5SDimitry Andric if (!NonVirtualOffset.isZero() || VirtualOffset) 25610b57cec5SDimitry Andric VTableField = ApplyNonVirtualAndVirtualOffset( 25620b57cec5SDimitry Andric *this, VTableField, NonVirtualOffset, VirtualOffset, Vptr.VTableClass, 25630b57cec5SDimitry Andric Vptr.NearestVBase); 25640b57cec5SDimitry Andric 25650b57cec5SDimitry Andric // Finally, store the address point. Use the same LLVM types as the field to 25660b57cec5SDimitry Andric // support optimization. 2567e8d8bef9SDimitry Andric unsigned GlobalsAS = CGM.getDataLayout().getDefaultGlobalsAddressSpace(); 256806c3fb27SDimitry Andric llvm::Type *PtrTy = llvm::PointerType::get(CGM.getLLVMContext(), GlobalsAS); 2569bdd1243dSDimitry Andric // vtable field is derived from `this` pointer, therefore they should be in 2570349cc55cSDimitry Andric // the same addr space. Note that this might not be LLVM address space 0. 257106c3fb27SDimitry Andric VTableField = VTableField.withElementType(PtrTy); 25720b57cec5SDimitry Andric 25730b57cec5SDimitry Andric llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField); 257406c3fb27SDimitry Andric TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(PtrTy); 25750b57cec5SDimitry Andric CGM.DecorateInstructionWithTBAA(Store, TBAAInfo); 25760b57cec5SDimitry Andric if (CGM.getCodeGenOpts().OptimizationLevel > 0 && 25770b57cec5SDimitry Andric CGM.getCodeGenOpts().StrictVTablePointers) 25780b57cec5SDimitry Andric CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.VTableClass); 25790b57cec5SDimitry Andric } 25800b57cec5SDimitry Andric 25810b57cec5SDimitry Andric CodeGenFunction::VPtrsVector 25820b57cec5SDimitry Andric CodeGenFunction::getVTablePointers(const CXXRecordDecl *VTableClass) { 25830b57cec5SDimitry Andric CodeGenFunction::VPtrsVector VPtrsResult; 25840b57cec5SDimitry Andric VisitedVirtualBasesSetTy VBases; 25850b57cec5SDimitry Andric getVTablePointers(BaseSubobject(VTableClass, CharUnits::Zero()), 25860b57cec5SDimitry Andric /*NearestVBase=*/nullptr, 25870b57cec5SDimitry Andric /*OffsetFromNearestVBase=*/CharUnits::Zero(), 25880b57cec5SDimitry Andric /*BaseIsNonVirtualPrimaryBase=*/false, VTableClass, VBases, 25890b57cec5SDimitry Andric VPtrsResult); 25900b57cec5SDimitry Andric return VPtrsResult; 25910b57cec5SDimitry Andric } 25920b57cec5SDimitry Andric 25930b57cec5SDimitry Andric void CodeGenFunction::getVTablePointers(BaseSubobject Base, 25940b57cec5SDimitry Andric const CXXRecordDecl *NearestVBase, 25950b57cec5SDimitry Andric CharUnits OffsetFromNearestVBase, 25960b57cec5SDimitry Andric bool BaseIsNonVirtualPrimaryBase, 25970b57cec5SDimitry Andric const CXXRecordDecl *VTableClass, 25980b57cec5SDimitry Andric VisitedVirtualBasesSetTy &VBases, 25990b57cec5SDimitry Andric VPtrsVector &Vptrs) { 26000b57cec5SDimitry Andric // If this base is a non-virtual primary base the address point has already 26010b57cec5SDimitry Andric // been set. 26020b57cec5SDimitry Andric if (!BaseIsNonVirtualPrimaryBase) { 26030b57cec5SDimitry Andric // Initialize the vtable pointer for this base. 26040b57cec5SDimitry Andric VPtr Vptr = {Base, NearestVBase, OffsetFromNearestVBase, VTableClass}; 26050b57cec5SDimitry Andric Vptrs.push_back(Vptr); 26060b57cec5SDimitry Andric } 26070b57cec5SDimitry Andric 26080b57cec5SDimitry Andric const CXXRecordDecl *RD = Base.getBase(); 26090b57cec5SDimitry Andric 26100b57cec5SDimitry Andric // Traverse bases. 26110b57cec5SDimitry Andric for (const auto &I : RD->bases()) { 2612a7dea167SDimitry Andric auto *BaseDecl = 2613a7dea167SDimitry Andric cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 26140b57cec5SDimitry Andric 26150b57cec5SDimitry Andric // Ignore classes without a vtable. 26160b57cec5SDimitry Andric if (!BaseDecl->isDynamicClass()) 26170b57cec5SDimitry Andric continue; 26180b57cec5SDimitry Andric 26190b57cec5SDimitry Andric CharUnits BaseOffset; 26200b57cec5SDimitry Andric CharUnits BaseOffsetFromNearestVBase; 26210b57cec5SDimitry Andric bool BaseDeclIsNonVirtualPrimaryBase; 26220b57cec5SDimitry Andric 26230b57cec5SDimitry Andric if (I.isVirtual()) { 26240b57cec5SDimitry Andric // Check if we've visited this virtual base before. 26250b57cec5SDimitry Andric if (!VBases.insert(BaseDecl).second) 26260b57cec5SDimitry Andric continue; 26270b57cec5SDimitry Andric 26280b57cec5SDimitry Andric const ASTRecordLayout &Layout = 26290b57cec5SDimitry Andric getContext().getASTRecordLayout(VTableClass); 26300b57cec5SDimitry Andric 26310b57cec5SDimitry Andric BaseOffset = Layout.getVBaseClassOffset(BaseDecl); 26320b57cec5SDimitry Andric BaseOffsetFromNearestVBase = CharUnits::Zero(); 26330b57cec5SDimitry Andric BaseDeclIsNonVirtualPrimaryBase = false; 26340b57cec5SDimitry Andric } else { 26350b57cec5SDimitry Andric const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 26360b57cec5SDimitry Andric 26370b57cec5SDimitry Andric BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl); 26380b57cec5SDimitry Andric BaseOffsetFromNearestVBase = 26390b57cec5SDimitry Andric OffsetFromNearestVBase + Layout.getBaseClassOffset(BaseDecl); 26400b57cec5SDimitry Andric BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl; 26410b57cec5SDimitry Andric } 26420b57cec5SDimitry Andric 26430b57cec5SDimitry Andric getVTablePointers( 26440b57cec5SDimitry Andric BaseSubobject(BaseDecl, BaseOffset), 26450b57cec5SDimitry Andric I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase, 26460b57cec5SDimitry Andric BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs); 26470b57cec5SDimitry Andric } 26480b57cec5SDimitry Andric } 26490b57cec5SDimitry Andric 26500b57cec5SDimitry Andric void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) { 26510b57cec5SDimitry Andric // Ignore classes without a vtable. 26520b57cec5SDimitry Andric if (!RD->isDynamicClass()) 26530b57cec5SDimitry Andric return; 26540b57cec5SDimitry Andric 26550b57cec5SDimitry Andric // Initialize the vtable pointers for this class and all of its bases. 26560b57cec5SDimitry Andric if (CGM.getCXXABI().doStructorsInitializeVPtrs(RD)) 26570b57cec5SDimitry Andric for (const VPtr &Vptr : getVTablePointers(RD)) 26580b57cec5SDimitry Andric InitializeVTablePointer(Vptr); 26590b57cec5SDimitry Andric 26600b57cec5SDimitry Andric if (RD->getNumVBases()) 26610b57cec5SDimitry Andric CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, RD); 26620b57cec5SDimitry Andric } 26630b57cec5SDimitry Andric 26640b57cec5SDimitry Andric llvm::Value *CodeGenFunction::GetVTablePtr(Address This, 26650b57cec5SDimitry Andric llvm::Type *VTableTy, 26660b57cec5SDimitry Andric const CXXRecordDecl *RD) { 266706c3fb27SDimitry Andric Address VTablePtrSrc = This.withElementType(VTableTy); 26680b57cec5SDimitry Andric llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable"); 26690b57cec5SDimitry Andric TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy); 26700b57cec5SDimitry Andric CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo); 26710b57cec5SDimitry Andric 26720b57cec5SDimitry Andric if (CGM.getCodeGenOpts().OptimizationLevel > 0 && 26730b57cec5SDimitry Andric CGM.getCodeGenOpts().StrictVTablePointers) 26740b57cec5SDimitry Andric CGM.DecorateInstructionWithInvariantGroup(VTable, RD); 26750b57cec5SDimitry Andric 26760b57cec5SDimitry Andric return VTable; 26770b57cec5SDimitry Andric } 26780b57cec5SDimitry Andric 26790b57cec5SDimitry Andric // If a class has a single non-virtual base and does not introduce or override 26800b57cec5SDimitry Andric // virtual member functions or fields, it will have the same layout as its base. 26810b57cec5SDimitry Andric // This function returns the least derived such class. 26820b57cec5SDimitry Andric // 26830b57cec5SDimitry Andric // Casting an instance of a base class to such a derived class is technically 26840b57cec5SDimitry Andric // undefined behavior, but it is a relatively common hack for introducing member 26850b57cec5SDimitry Andric // functions on class instances with specific properties (e.g. llvm::Operator) 26860b57cec5SDimitry Andric // that works under most compilers and should not have security implications, so 26870b57cec5SDimitry Andric // we allow it by default. It can be disabled with -fsanitize=cfi-cast-strict. 26880b57cec5SDimitry Andric static const CXXRecordDecl * 26890b57cec5SDimitry Andric LeastDerivedClassWithSameLayout(const CXXRecordDecl *RD) { 26900b57cec5SDimitry Andric if (!RD->field_empty()) 26910b57cec5SDimitry Andric return RD; 26920b57cec5SDimitry Andric 26930b57cec5SDimitry Andric if (RD->getNumVBases() != 0) 26940b57cec5SDimitry Andric return RD; 26950b57cec5SDimitry Andric 26960b57cec5SDimitry Andric if (RD->getNumBases() != 1) 26970b57cec5SDimitry Andric return RD; 26980b57cec5SDimitry Andric 26990b57cec5SDimitry Andric for (const CXXMethodDecl *MD : RD->methods()) { 27000b57cec5SDimitry Andric if (MD->isVirtual()) { 27010b57cec5SDimitry Andric // Virtual member functions are only ok if they are implicit destructors 27020b57cec5SDimitry Andric // because the implicit destructor will have the same semantics as the 27030b57cec5SDimitry Andric // base class's destructor if no fields are added. 27040b57cec5SDimitry Andric if (isa<CXXDestructorDecl>(MD) && MD->isImplicit()) 27050b57cec5SDimitry Andric continue; 27060b57cec5SDimitry Andric return RD; 27070b57cec5SDimitry Andric } 27080b57cec5SDimitry Andric } 27090b57cec5SDimitry Andric 27100b57cec5SDimitry Andric return LeastDerivedClassWithSameLayout( 27110b57cec5SDimitry Andric RD->bases_begin()->getType()->getAsCXXRecordDecl()); 27120b57cec5SDimitry Andric } 27130b57cec5SDimitry Andric 27140b57cec5SDimitry Andric void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, 27150b57cec5SDimitry Andric llvm::Value *VTable, 27160b57cec5SDimitry Andric SourceLocation Loc) { 27170b57cec5SDimitry Andric if (SanOpts.has(SanitizerKind::CFIVCall)) 27180b57cec5SDimitry Andric EmitVTablePtrCheckForCall(RD, VTable, CodeGenFunction::CFITCK_VCall, Loc); 27190b57cec5SDimitry Andric else if (CGM.getCodeGenOpts().WholeProgramVTables && 272081ad6265SDimitry Andric // Don't insert type test assumes if we are forcing public 27215ffd83dbSDimitry Andric // visibility. 272281ad6265SDimitry Andric !CGM.AlwaysHasLTOVisibilityPublic(RD)) { 2723972a253aSDimitry Andric QualType Ty = QualType(RD->getTypeForDecl(), 0); 2724972a253aSDimitry Andric llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(Ty); 27250b57cec5SDimitry Andric llvm::Value *TypeId = 27260b57cec5SDimitry Andric llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD); 27270b57cec5SDimitry Andric 2728972a253aSDimitry Andric // If we already know that the call has hidden LTO visibility, emit 2729972a253aSDimitry Andric // @llvm.type.test(). Otherwise emit @llvm.public.type.test(), which WPD 2730972a253aSDimitry Andric // will convert to @llvm.type.test() if we assert at link time that we have 2731972a253aSDimitry Andric // whole program visibility. 2732972a253aSDimitry Andric llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD) 2733972a253aSDimitry Andric ? llvm::Intrinsic::type_test 2734972a253aSDimitry Andric : llvm::Intrinsic::public_type_test; 27350b57cec5SDimitry Andric llvm::Value *TypeTest = 27365f757f3fSDimitry Andric Builder.CreateCall(CGM.getIntrinsic(IID), {VTable, TypeId}); 27370b57cec5SDimitry Andric Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest); 27380b57cec5SDimitry Andric } 27390b57cec5SDimitry Andric } 27400b57cec5SDimitry Andric 27410b57cec5SDimitry Andric void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, 27420b57cec5SDimitry Andric llvm::Value *VTable, 27430b57cec5SDimitry Andric CFITypeCheckKind TCK, 27440b57cec5SDimitry Andric SourceLocation Loc) { 27450b57cec5SDimitry Andric if (!SanOpts.has(SanitizerKind::CFICastStrict)) 27460b57cec5SDimitry Andric RD = LeastDerivedClassWithSameLayout(RD); 27470b57cec5SDimitry Andric 27480b57cec5SDimitry Andric EmitVTablePtrCheck(RD, VTable, TCK, Loc); 27490b57cec5SDimitry Andric } 27500b57cec5SDimitry Andric 275181ad6265SDimitry Andric void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived, 27520b57cec5SDimitry Andric bool MayBeNull, 27530b57cec5SDimitry Andric CFITypeCheckKind TCK, 27540b57cec5SDimitry Andric SourceLocation Loc) { 27550b57cec5SDimitry Andric if (!getLangOpts().CPlusPlus) 27560b57cec5SDimitry Andric return; 27570b57cec5SDimitry Andric 27580b57cec5SDimitry Andric auto *ClassTy = T->getAs<RecordType>(); 27590b57cec5SDimitry Andric if (!ClassTy) 27600b57cec5SDimitry Andric return; 27610b57cec5SDimitry Andric 27620b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassTy->getDecl()); 27630b57cec5SDimitry Andric 27640b57cec5SDimitry Andric if (!ClassDecl->isCompleteDefinition() || !ClassDecl->isDynamicClass()) 27650b57cec5SDimitry Andric return; 27660b57cec5SDimitry Andric 27670b57cec5SDimitry Andric if (!SanOpts.has(SanitizerKind::CFICastStrict)) 27680b57cec5SDimitry Andric ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl); 27690b57cec5SDimitry Andric 27700b57cec5SDimitry Andric llvm::BasicBlock *ContBlock = nullptr; 27710b57cec5SDimitry Andric 27720b57cec5SDimitry Andric if (MayBeNull) { 27730b57cec5SDimitry Andric llvm::Value *DerivedNotNull = 277481ad6265SDimitry Andric Builder.CreateIsNotNull(Derived.getPointer(), "cast.nonnull"); 27750b57cec5SDimitry Andric 27760b57cec5SDimitry Andric llvm::BasicBlock *CheckBlock = createBasicBlock("cast.check"); 27770b57cec5SDimitry Andric ContBlock = createBasicBlock("cast.cont"); 27780b57cec5SDimitry Andric 27790b57cec5SDimitry Andric Builder.CreateCondBr(DerivedNotNull, CheckBlock, ContBlock); 27800b57cec5SDimitry Andric 27810b57cec5SDimitry Andric EmitBlock(CheckBlock); 27820b57cec5SDimitry Andric } 27830b57cec5SDimitry Andric 27840b57cec5SDimitry Andric llvm::Value *VTable; 278581ad6265SDimitry Andric std::tie(VTable, ClassDecl) = 278681ad6265SDimitry Andric CGM.getCXXABI().LoadVTablePtr(*this, Derived, ClassDecl); 27870b57cec5SDimitry Andric 27880b57cec5SDimitry Andric EmitVTablePtrCheck(ClassDecl, VTable, TCK, Loc); 27890b57cec5SDimitry Andric 27900b57cec5SDimitry Andric if (MayBeNull) { 27910b57cec5SDimitry Andric Builder.CreateBr(ContBlock); 27920b57cec5SDimitry Andric EmitBlock(ContBlock); 27930b57cec5SDimitry Andric } 27940b57cec5SDimitry Andric } 27950b57cec5SDimitry Andric 27960b57cec5SDimitry Andric void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD, 27970b57cec5SDimitry Andric llvm::Value *VTable, 27980b57cec5SDimitry Andric CFITypeCheckKind TCK, 27990b57cec5SDimitry Andric SourceLocation Loc) { 28000b57cec5SDimitry Andric if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso && 28010b57cec5SDimitry Andric !CGM.HasHiddenLTOVisibility(RD)) 28020b57cec5SDimitry Andric return; 28030b57cec5SDimitry Andric 28040b57cec5SDimitry Andric SanitizerMask M; 28050b57cec5SDimitry Andric llvm::SanitizerStatKind SSK; 28060b57cec5SDimitry Andric switch (TCK) { 28070b57cec5SDimitry Andric case CFITCK_VCall: 28080b57cec5SDimitry Andric M = SanitizerKind::CFIVCall; 28090b57cec5SDimitry Andric SSK = llvm::SanStat_CFI_VCall; 28100b57cec5SDimitry Andric break; 28110b57cec5SDimitry Andric case CFITCK_NVCall: 28120b57cec5SDimitry Andric M = SanitizerKind::CFINVCall; 28130b57cec5SDimitry Andric SSK = llvm::SanStat_CFI_NVCall; 28140b57cec5SDimitry Andric break; 28150b57cec5SDimitry Andric case CFITCK_DerivedCast: 28160b57cec5SDimitry Andric M = SanitizerKind::CFIDerivedCast; 28170b57cec5SDimitry Andric SSK = llvm::SanStat_CFI_DerivedCast; 28180b57cec5SDimitry Andric break; 28190b57cec5SDimitry Andric case CFITCK_UnrelatedCast: 28200b57cec5SDimitry Andric M = SanitizerKind::CFIUnrelatedCast; 28210b57cec5SDimitry Andric SSK = llvm::SanStat_CFI_UnrelatedCast; 28220b57cec5SDimitry Andric break; 28230b57cec5SDimitry Andric case CFITCK_ICall: 28240b57cec5SDimitry Andric case CFITCK_NVMFCall: 28250b57cec5SDimitry Andric case CFITCK_VMFCall: 28260b57cec5SDimitry Andric llvm_unreachable("unexpected sanitizer kind"); 28270b57cec5SDimitry Andric } 28280b57cec5SDimitry Andric 28290b57cec5SDimitry Andric std::string TypeName = RD->getQualifiedNameAsString(); 2830fe6060f1SDimitry Andric if (getContext().getNoSanitizeList().containsType(M, TypeName)) 28310b57cec5SDimitry Andric return; 28320b57cec5SDimitry Andric 28330b57cec5SDimitry Andric SanitizerScope SanScope(this); 28340b57cec5SDimitry Andric EmitSanitizerStatReport(SSK); 28350b57cec5SDimitry Andric 28360b57cec5SDimitry Andric llvm::Metadata *MD = 28370b57cec5SDimitry Andric CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)); 28380b57cec5SDimitry Andric llvm::Value *TypeId = llvm::MetadataAsValue::get(getLLVMContext(), MD); 28390b57cec5SDimitry Andric 28400b57cec5SDimitry Andric llvm::Value *TypeTest = Builder.CreateCall( 28415f757f3fSDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, TypeId}); 28420b57cec5SDimitry Andric 28430b57cec5SDimitry Andric llvm::Constant *StaticData[] = { 28440b57cec5SDimitry Andric llvm::ConstantInt::get(Int8Ty, TCK), 28450b57cec5SDimitry Andric EmitCheckSourceLocation(Loc), 28460b57cec5SDimitry Andric EmitCheckTypeDescriptor(QualType(RD->getTypeForDecl(), 0)), 28470b57cec5SDimitry Andric }; 28480b57cec5SDimitry Andric 28490b57cec5SDimitry Andric auto CrossDsoTypeId = CGM.CreateCrossDsoCfiTypeId(MD); 28500b57cec5SDimitry Andric if (CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) { 28515f757f3fSDimitry Andric EmitCfiSlowPathCheck(M, TypeTest, CrossDsoTypeId, VTable, StaticData); 28520b57cec5SDimitry Andric return; 28530b57cec5SDimitry Andric } 28540b57cec5SDimitry Andric 28550b57cec5SDimitry Andric if (CGM.getCodeGenOpts().SanitizeTrap.has(M)) { 2856e8d8bef9SDimitry Andric EmitTrapCheck(TypeTest, SanitizerHandler::CFICheckFail); 28570b57cec5SDimitry Andric return; 28580b57cec5SDimitry Andric } 28590b57cec5SDimitry Andric 28600b57cec5SDimitry Andric llvm::Value *AllVtables = llvm::MetadataAsValue::get( 28610b57cec5SDimitry Andric CGM.getLLVMContext(), 28620b57cec5SDimitry Andric llvm::MDString::get(CGM.getLLVMContext(), "all-vtables")); 28630b57cec5SDimitry Andric llvm::Value *ValidVtable = Builder.CreateCall( 28645f757f3fSDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables}); 28650b57cec5SDimitry Andric EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail, 28665f757f3fSDimitry Andric StaticData, {VTable, ValidVtable}); 28670b57cec5SDimitry Andric } 28680b57cec5SDimitry Andric 28690b57cec5SDimitry Andric bool CodeGenFunction::ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD) { 28700b57cec5SDimitry Andric if (!CGM.getCodeGenOpts().WholeProgramVTables || 28710b57cec5SDimitry Andric !CGM.HasHiddenLTOVisibility(RD)) 28720b57cec5SDimitry Andric return false; 28730b57cec5SDimitry Andric 2874a7dea167SDimitry Andric if (CGM.getCodeGenOpts().VirtualFunctionElimination) 2875a7dea167SDimitry Andric return true; 2876a7dea167SDimitry Andric 2877a7dea167SDimitry Andric if (!SanOpts.has(SanitizerKind::CFIVCall) || 2878a7dea167SDimitry Andric !CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIVCall)) 2879a7dea167SDimitry Andric return false; 2880a7dea167SDimitry Andric 28810b57cec5SDimitry Andric std::string TypeName = RD->getQualifiedNameAsString(); 2882fe6060f1SDimitry Andric return !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall, 2883fe6060f1SDimitry Andric TypeName); 28840b57cec5SDimitry Andric } 28850b57cec5SDimitry Andric 28860b57cec5SDimitry Andric llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad( 288781ad6265SDimitry Andric const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, 288881ad6265SDimitry Andric uint64_t VTableByteOffset) { 28890b57cec5SDimitry Andric SanitizerScope SanScope(this); 28900b57cec5SDimitry Andric 28910b57cec5SDimitry Andric EmitSanitizerStatReport(llvm::SanStat_CFI_VCall); 28920b57cec5SDimitry Andric 28930b57cec5SDimitry Andric llvm::Metadata *MD = 28940b57cec5SDimitry Andric CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)); 28950b57cec5SDimitry Andric llvm::Value *TypeId = llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD); 28960b57cec5SDimitry Andric 28970b57cec5SDimitry Andric llvm::Value *CheckedLoad = Builder.CreateCall( 28980b57cec5SDimitry Andric CGM.getIntrinsic(llvm::Intrinsic::type_checked_load), 28995f757f3fSDimitry Andric {VTable, llvm::ConstantInt::get(Int32Ty, VTableByteOffset), TypeId}); 29000b57cec5SDimitry Andric llvm::Value *CheckResult = Builder.CreateExtractValue(CheckedLoad, 1); 29010b57cec5SDimitry Andric 2902a7dea167SDimitry Andric std::string TypeName = RD->getQualifiedNameAsString(); 2903a7dea167SDimitry Andric if (SanOpts.has(SanitizerKind::CFIVCall) && 2904fe6060f1SDimitry Andric !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall, 2905fe6060f1SDimitry Andric TypeName)) { 29060b57cec5SDimitry Andric EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIVCall), 2907a7dea167SDimitry Andric SanitizerHandler::CFICheckFail, {}, {}); 2908a7dea167SDimitry Andric } 29090b57cec5SDimitry Andric 291004eeddc0SDimitry Andric return Builder.CreateBitCast(Builder.CreateExtractValue(CheckedLoad, 0), 291181ad6265SDimitry Andric VTableTy); 29120b57cec5SDimitry Andric } 29130b57cec5SDimitry Andric 29140b57cec5SDimitry Andric void CodeGenFunction::EmitForwardingCallToLambda( 29158a4dda33SDimitry Andric const CXXMethodDecl *callOperator, CallArgList &callArgs, 29168a4dda33SDimitry Andric const CGFunctionInfo *calleeFnInfo, llvm::Constant *calleePtr) { 29170b57cec5SDimitry Andric // Get the address of the call operator. 29188a4dda33SDimitry Andric if (!calleeFnInfo) 29198a4dda33SDimitry Andric calleeFnInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(callOperator); 29208a4dda33SDimitry Andric 29218a4dda33SDimitry Andric if (!calleePtr) 29228a4dda33SDimitry Andric calleePtr = 29230b57cec5SDimitry Andric CGM.GetAddrOfFunction(GlobalDecl(callOperator), 29248a4dda33SDimitry Andric CGM.getTypes().GetFunctionType(*calleeFnInfo)); 29250b57cec5SDimitry Andric 29260b57cec5SDimitry Andric // Prepare the return slot. 29270b57cec5SDimitry Andric const FunctionProtoType *FPT = 29280b57cec5SDimitry Andric callOperator->getType()->castAs<FunctionProtoType>(); 29290b57cec5SDimitry Andric QualType resultType = FPT->getReturnType(); 29300b57cec5SDimitry Andric ReturnValueSlot returnSlot; 29310b57cec5SDimitry Andric if (!resultType->isVoidType() && 29328a4dda33SDimitry Andric calleeFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect && 29338a4dda33SDimitry Andric !hasScalarEvaluationKind(calleeFnInfo->getReturnType())) 29345ffd83dbSDimitry Andric returnSlot = 29355ffd83dbSDimitry Andric ReturnValueSlot(ReturnValue, resultType.isVolatileQualified(), 29365ffd83dbSDimitry Andric /*IsUnused=*/false, /*IsExternallyDestructed=*/true); 29370b57cec5SDimitry Andric 29380b57cec5SDimitry Andric // We don't need to separately arrange the call arguments because 29390b57cec5SDimitry Andric // the call can't be variadic anyway --- it's impossible to forward 29400b57cec5SDimitry Andric // variadic arguments. 29410b57cec5SDimitry Andric 29420b57cec5SDimitry Andric // Now emit our call. 29430b57cec5SDimitry Andric auto callee = CGCallee::forDirect(calleePtr, GlobalDecl(callOperator)); 29448a4dda33SDimitry Andric RValue RV = EmitCall(*calleeFnInfo, callee, returnSlot, callArgs); 29450b57cec5SDimitry Andric 29460b57cec5SDimitry Andric // If necessary, copy the returned value into the slot. 29470b57cec5SDimitry Andric if (!resultType->isVoidType() && returnSlot.isNull()) { 29480b57cec5SDimitry Andric if (getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType()) { 29490b57cec5SDimitry Andric RV = RValue::get(EmitARCRetainAutoreleasedReturnValue(RV.getScalarVal())); 29500b57cec5SDimitry Andric } 29510b57cec5SDimitry Andric EmitReturnOfRValue(RV, resultType); 29520b57cec5SDimitry Andric } else 29530b57cec5SDimitry Andric EmitBranchThroughCleanup(ReturnBlock); 29540b57cec5SDimitry Andric } 29550b57cec5SDimitry Andric 29560b57cec5SDimitry Andric void CodeGenFunction::EmitLambdaBlockInvokeBody() { 29570b57cec5SDimitry Andric const BlockDecl *BD = BlockInfo->getBlockDecl(); 29580b57cec5SDimitry Andric const VarDecl *variable = BD->capture_begin()->getVariable(); 29590b57cec5SDimitry Andric const CXXRecordDecl *Lambda = variable->getType()->getAsCXXRecordDecl(); 29600b57cec5SDimitry Andric const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator(); 29610b57cec5SDimitry Andric 29620b57cec5SDimitry Andric if (CallOp->isVariadic()) { 29630b57cec5SDimitry Andric // FIXME: Making this work correctly is nasty because it requires either 29640b57cec5SDimitry Andric // cloning the body of the call operator or making the call operator 29650b57cec5SDimitry Andric // forward. 29660b57cec5SDimitry Andric CGM.ErrorUnsupported(CurCodeDecl, "lambda conversion to variadic function"); 29670b57cec5SDimitry Andric return; 29680b57cec5SDimitry Andric } 29690b57cec5SDimitry Andric 29700b57cec5SDimitry Andric // Start building arguments for forwarding call 29710b57cec5SDimitry Andric CallArgList CallArgs; 29720b57cec5SDimitry Andric 29730b57cec5SDimitry Andric QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda)); 29740b57cec5SDimitry Andric Address ThisPtr = GetAddrOfBlockDecl(variable); 29750b57cec5SDimitry Andric CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType); 29760b57cec5SDimitry Andric 29770b57cec5SDimitry Andric // Add the rest of the parameters. 2978bdd1243dSDimitry Andric for (auto *param : BD->parameters()) 29790b57cec5SDimitry Andric EmitDelegateCallArg(CallArgs, param, param->getBeginLoc()); 29800b57cec5SDimitry Andric 29810b57cec5SDimitry Andric assert(!Lambda->isGenericLambda() && 29820b57cec5SDimitry Andric "generic lambda interconversion to block not implemented"); 29830b57cec5SDimitry Andric EmitForwardingCallToLambda(CallOp, CallArgs); 29840b57cec5SDimitry Andric } 29850b57cec5SDimitry Andric 29868a4dda33SDimitry Andric void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) { 29878a4dda33SDimitry Andric if (MD->isVariadic()) { 29888a4dda33SDimitry Andric // FIXME: Making this work correctly is nasty because it requires either 29898a4dda33SDimitry Andric // cloning the body of the call operator or making the call operator 29908a4dda33SDimitry Andric // forward. 29918a4dda33SDimitry Andric CGM.ErrorUnsupported(MD, "lambda conversion to variadic function"); 29928a4dda33SDimitry Andric return; 29938a4dda33SDimitry Andric } 29948a4dda33SDimitry Andric 29950b57cec5SDimitry Andric const CXXRecordDecl *Lambda = MD->getParent(); 29960b57cec5SDimitry Andric 29970b57cec5SDimitry Andric // Start building arguments for forwarding call 29980b57cec5SDimitry Andric CallArgList CallArgs; 29990b57cec5SDimitry Andric 3000bdd1243dSDimitry Andric QualType LambdaType = getContext().getRecordType(Lambda); 3001bdd1243dSDimitry Andric QualType ThisType = getContext().getPointerType(LambdaType); 3002bdd1243dSDimitry Andric Address ThisPtr = CreateMemTemp(LambdaType, "unused.capture"); 3003bdd1243dSDimitry Andric CallArgs.add(RValue::get(ThisPtr.getPointer()), ThisType); 30040b57cec5SDimitry Andric 30058a4dda33SDimitry Andric EmitLambdaDelegatingInvokeBody(MD, CallArgs); 30068a4dda33SDimitry Andric } 30078a4dda33SDimitry Andric 30088a4dda33SDimitry Andric void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD, 30098a4dda33SDimitry Andric CallArgList &CallArgs) { 30108a4dda33SDimitry Andric // Add the rest of the forwarded parameters. 3011bdd1243dSDimitry Andric for (auto *Param : MD->parameters()) 30120b57cec5SDimitry Andric EmitDelegateCallArg(CallArgs, Param, Param->getBeginLoc()); 30130b57cec5SDimitry Andric 30148a4dda33SDimitry Andric const CXXRecordDecl *Lambda = MD->getParent(); 30150b57cec5SDimitry Andric const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator(); 30160b57cec5SDimitry Andric // For a generic lambda, find the corresponding call operator specialization 30170b57cec5SDimitry Andric // to which the call to the static-invoker shall be forwarded. 30180b57cec5SDimitry Andric if (Lambda->isGenericLambda()) { 30190b57cec5SDimitry Andric assert(MD->isFunctionTemplateSpecialization()); 30200b57cec5SDimitry Andric const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs(); 30210b57cec5SDimitry Andric FunctionTemplateDecl *CallOpTemplate = CallOp->getDescribedFunctionTemplate(); 30220b57cec5SDimitry Andric void *InsertPos = nullptr; 30230b57cec5SDimitry Andric FunctionDecl *CorrespondingCallOpSpecialization = 30240b57cec5SDimitry Andric CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos); 30250b57cec5SDimitry Andric assert(CorrespondingCallOpSpecialization); 30260b57cec5SDimitry Andric CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization); 30270b57cec5SDimitry Andric } 30288a4dda33SDimitry Andric 30298a4dda33SDimitry Andric // Special lambda forwarding when there are inalloca parameters. 30308a4dda33SDimitry Andric if (hasInAllocaArg(MD)) { 30318a4dda33SDimitry Andric const CGFunctionInfo *ImplFnInfo = nullptr; 30328a4dda33SDimitry Andric llvm::Function *ImplFn = nullptr; 30338a4dda33SDimitry Andric EmitLambdaInAllocaImplFn(CallOp, &ImplFnInfo, &ImplFn); 30348a4dda33SDimitry Andric 30358a4dda33SDimitry Andric EmitForwardingCallToLambda(CallOp, CallArgs, ImplFnInfo, ImplFn); 30368a4dda33SDimitry Andric return; 30378a4dda33SDimitry Andric } 30388a4dda33SDimitry Andric 30390b57cec5SDimitry Andric EmitForwardingCallToLambda(CallOp, CallArgs); 30400b57cec5SDimitry Andric } 30410b57cec5SDimitry Andric 30428a4dda33SDimitry Andric void CodeGenFunction::EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD) { 30430b57cec5SDimitry Andric if (MD->isVariadic()) { 30440b57cec5SDimitry Andric // FIXME: Making this work correctly is nasty because it requires either 30450b57cec5SDimitry Andric // cloning the body of the call operator or making the call operator forward. 30460b57cec5SDimitry Andric CGM.ErrorUnsupported(MD, "lambda conversion to variadic function"); 30470b57cec5SDimitry Andric return; 30480b57cec5SDimitry Andric } 30490b57cec5SDimitry Andric 30508a4dda33SDimitry Andric // Forward %this argument. 30518a4dda33SDimitry Andric CallArgList CallArgs; 30528a4dda33SDimitry Andric QualType LambdaType = getContext().getRecordType(MD->getParent()); 30538a4dda33SDimitry Andric QualType ThisType = getContext().getPointerType(LambdaType); 30548a4dda33SDimitry Andric llvm::Value *ThisArg = CurFn->getArg(0); 30558a4dda33SDimitry Andric CallArgs.add(RValue::get(ThisArg), ThisType); 30568a4dda33SDimitry Andric 30578a4dda33SDimitry Andric EmitLambdaDelegatingInvokeBody(MD, CallArgs); 30588a4dda33SDimitry Andric } 30598a4dda33SDimitry Andric 30608a4dda33SDimitry Andric void CodeGenFunction::EmitLambdaInAllocaImplFn( 30618a4dda33SDimitry Andric const CXXMethodDecl *CallOp, const CGFunctionInfo **ImplFnInfo, 30628a4dda33SDimitry Andric llvm::Function **ImplFn) { 30638a4dda33SDimitry Andric const CGFunctionInfo &FnInfo = 30648a4dda33SDimitry Andric CGM.getTypes().arrangeCXXMethodDeclaration(CallOp); 30658a4dda33SDimitry Andric llvm::Function *CallOpFn = 30668a4dda33SDimitry Andric cast<llvm::Function>(CGM.GetAddrOfFunction(GlobalDecl(CallOp))); 30678a4dda33SDimitry Andric 30688a4dda33SDimitry Andric // Emit function containing the original call op body. __invoke will delegate 30698a4dda33SDimitry Andric // to this function. 30708a4dda33SDimitry Andric SmallVector<CanQualType, 4> ArgTypes; 30718a4dda33SDimitry Andric for (auto I = FnInfo.arg_begin(); I != FnInfo.arg_end(); ++I) 30728a4dda33SDimitry Andric ArgTypes.push_back(I->type); 30738a4dda33SDimitry Andric *ImplFnInfo = &CGM.getTypes().arrangeLLVMFunctionInfo( 30748a4dda33SDimitry Andric FnInfo.getReturnType(), FnInfoOpts::IsDelegateCall, ArgTypes, 30758a4dda33SDimitry Andric FnInfo.getExtInfo(), {}, FnInfo.getRequiredArgs()); 30768a4dda33SDimitry Andric 30778a4dda33SDimitry Andric // Create mangled name as if this was a method named __impl. If for some 30788a4dda33SDimitry Andric // reason the name doesn't look as expected then just tack __impl to the 30798a4dda33SDimitry Andric // front. 30808a4dda33SDimitry Andric // TODO: Use the name mangler to produce the right name instead of using 30818a4dda33SDimitry Andric // string replacement. 30828a4dda33SDimitry Andric StringRef CallOpName = CallOpFn->getName(); 30838a4dda33SDimitry Andric std::string ImplName; 30848a4dda33SDimitry Andric if (size_t Pos = CallOpName.find_first_of("<lambda")) 30858a4dda33SDimitry Andric ImplName = ("?__impl@" + CallOpName.drop_front(Pos)).str(); 30868a4dda33SDimitry Andric else 30878a4dda33SDimitry Andric ImplName = ("__impl" + CallOpName).str(); 30888a4dda33SDimitry Andric 30898a4dda33SDimitry Andric llvm::Function *Fn = CallOpFn->getParent()->getFunction(ImplName); 30908a4dda33SDimitry Andric if (!Fn) { 30918a4dda33SDimitry Andric Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(**ImplFnInfo), 30928a4dda33SDimitry Andric llvm::GlobalValue::InternalLinkage, ImplName, 30938a4dda33SDimitry Andric CGM.getModule()); 30948a4dda33SDimitry Andric CGM.SetInternalFunctionAttributes(CallOp, Fn, **ImplFnInfo); 30958a4dda33SDimitry Andric 30968a4dda33SDimitry Andric const GlobalDecl &GD = GlobalDecl(CallOp); 30978a4dda33SDimitry Andric const auto *D = cast<FunctionDecl>(GD.getDecl()); 30988a4dda33SDimitry Andric CodeGenFunction(CGM).GenerateCode(GD, Fn, **ImplFnInfo); 30998a4dda33SDimitry Andric CGM.SetLLVMFunctionAttributesForDefinition(D, Fn); 31008a4dda33SDimitry Andric } 31018a4dda33SDimitry Andric *ImplFn = Fn; 31020b57cec5SDimitry Andric } 3103