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