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