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