xref: /src/contrib/llvm-project/clang/lib/CodeGen/CGClass.cpp (revision 5deeebd8c6ca991269e72902a7a62cada57947f6)
145b53394SDimitry Andric //===--- CGClass.cpp - Emit LLVM Code for C++ classes -----------*- C++ -*-===//
21569ce68SRoman Divacky //
322989816SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
422989816SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
522989816SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61569ce68SRoman Divacky //
71569ce68SRoman Divacky //===----------------------------------------------------------------------===//
81569ce68SRoman Divacky //
91569ce68SRoman Divacky // This contains code dealing with C++ code generation of classes
101569ce68SRoman Divacky //
111569ce68SRoman Divacky //===----------------------------------------------------------------------===//
121569ce68SRoman Divacky 
13ac9a064cSDimitry Andric #include "ABIInfoImpl.h"
14dbe13110SDimitry Andric #include "CGBlocks.h"
159f4dbff6SDimitry Andric #include "CGCXXABI.h"
163d1dcd9bSDimitry Andric #include "CGDebugInfo.h"
17809500fcSDimitry Andric #include "CGRecordLayout.h"
181569ce68SRoman Divacky #include "CodeGenFunction.h"
19676fbe81SDimitry Andric #include "TargetInfo.h"
20706b4fc4SDimitry Andric #include "clang/AST/Attr.h"
211569ce68SRoman Divacky #include "clang/AST/CXXInheritance.h"
22b60736ecSDimitry Andric #include "clang/AST/CharUnits.h"
23bfef3995SDimitry Andric #include "clang/AST/DeclTemplate.h"
24bca07a45SDimitry Andric #include "clang/AST/EvaluatedExprVisitor.h"
251569ce68SRoman Divacky #include "clang/AST/RecordLayout.h"
2679ade4e0SRoman Divacky #include "clang/AST/StmtCXX.h"
27676fbe81SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
28809500fcSDimitry Andric #include "clang/Basic/TargetBuiltins.h"
29bfef3995SDimitry Andric #include "clang/CodeGen/CGFunctionInfo.h"
305e20cdd8SDimitry Andric #include "llvm/IR/Intrinsics.h"
3145b53394SDimitry Andric #include "llvm/IR/Metadata.h"
32b1c73532SDimitry Andric #include "llvm/Support/SaveAndRestore.h"
332b6b257fSDimitry Andric #include "llvm/Transforms/Utils/SanitizerStats.h"
34e3b55780SDimitry Andric #include <optional>
351569ce68SRoman Divacky 
361569ce68SRoman Divacky using namespace clang;
371569ce68SRoman Divacky using namespace CodeGen;
381569ce68SRoman Divacky 
3945b53394SDimitry Andric /// Return the best known alignment for an unknown pointer to a
4045b53394SDimitry Andric /// particular class.
getClassPointerAlignment(const CXXRecordDecl * RD)4145b53394SDimitry Andric CharUnits CodeGenModule::getClassPointerAlignment(const CXXRecordDecl *RD) {
42cfca06d7SDimitry Andric   if (!RD->hasDefinition())
4345b53394SDimitry Andric     return CharUnits::One(); // Hopefully won't be used anywhere.
4445b53394SDimitry Andric 
4545b53394SDimitry Andric   auto &layout = getContext().getASTRecordLayout(RD);
4645b53394SDimitry Andric 
4745b53394SDimitry Andric   // If the class is final, then we know that the pointer points to an
4845b53394SDimitry Andric   // object of that type and can use the full alignment.
49cfca06d7SDimitry Andric   if (RD->isEffectivelyFinal())
5045b53394SDimitry Andric     return layout.getAlignment();
5145b53394SDimitry Andric 
5245b53394SDimitry Andric   // Otherwise, we have to assume it could be a subclass.
5345b53394SDimitry Andric   return layout.getNonVirtualAlignment();
5445b53394SDimitry Andric }
55cfca06d7SDimitry Andric 
56cfca06d7SDimitry Andric /// Return the smallest possible amount of storage that might be allocated
57cfca06d7SDimitry Andric /// starting from the beginning of an object of a particular class.
58cfca06d7SDimitry Andric ///
59cfca06d7SDimitry Andric /// This may be smaller than sizeof(RD) if RD has virtual base classes.
getMinimumClassObjectSize(const CXXRecordDecl * RD)60cfca06d7SDimitry Andric CharUnits CodeGenModule::getMinimumClassObjectSize(const CXXRecordDecl *RD) {
61cfca06d7SDimitry Andric   if (!RD->hasDefinition())
62cfca06d7SDimitry Andric     return CharUnits::One();
63cfca06d7SDimitry Andric 
64cfca06d7SDimitry Andric   auto &layout = getContext().getASTRecordLayout(RD);
65cfca06d7SDimitry Andric 
66cfca06d7SDimitry Andric   // If the class is final, then we know that the pointer points to an
67cfca06d7SDimitry Andric   // object of that type and can use the full alignment.
68cfca06d7SDimitry Andric   if (RD->isEffectivelyFinal())
69cfca06d7SDimitry Andric     return layout.getSize();
70cfca06d7SDimitry Andric 
71cfca06d7SDimitry Andric   // Otherwise, we have to assume it could be a subclass.
72cfca06d7SDimitry Andric   return std::max(layout.getNonVirtualSize(), CharUnits::One());
7345b53394SDimitry Andric }
7445b53394SDimitry Andric 
7545b53394SDimitry Andric /// Return the best known alignment for a pointer to a virtual base,
7645b53394SDimitry Andric /// given the alignment of a pointer to the derived class.
getVBaseAlignment(CharUnits actualDerivedAlign,const CXXRecordDecl * derivedClass,const CXXRecordDecl * vbaseClass)7745b53394SDimitry Andric CharUnits CodeGenModule::getVBaseAlignment(CharUnits actualDerivedAlign,
7845b53394SDimitry Andric                                            const CXXRecordDecl *derivedClass,
7945b53394SDimitry Andric                                            const CXXRecordDecl *vbaseClass) {
8045b53394SDimitry Andric   // The basic idea here is that an underaligned derived pointer might
8145b53394SDimitry Andric   // indicate an underaligned base pointer.
8245b53394SDimitry Andric 
8345b53394SDimitry Andric   assert(vbaseClass->isCompleteDefinition());
8445b53394SDimitry Andric   auto &baseLayout = getContext().getASTRecordLayout(vbaseClass);
8545b53394SDimitry Andric   CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment();
8645b53394SDimitry Andric 
8745b53394SDimitry Andric   return getDynamicOffsetAlignment(actualDerivedAlign, derivedClass,
8845b53394SDimitry Andric                                    expectedVBaseAlign);
8945b53394SDimitry Andric }
9045b53394SDimitry Andric 
9145b53394SDimitry Andric CharUnits
getDynamicOffsetAlignment(CharUnits actualBaseAlign,const CXXRecordDecl * baseDecl,CharUnits expectedTargetAlign)9245b53394SDimitry Andric CodeGenModule::getDynamicOffsetAlignment(CharUnits actualBaseAlign,
9345b53394SDimitry Andric                                          const CXXRecordDecl *baseDecl,
9445b53394SDimitry Andric                                          CharUnits expectedTargetAlign) {
9545b53394SDimitry Andric   // If the base is an incomplete type (which is, alas, possible with
9645b53394SDimitry Andric   // member pointers), be pessimistic.
9745b53394SDimitry Andric   if (!baseDecl->isCompleteDefinition())
9845b53394SDimitry Andric     return std::min(actualBaseAlign, expectedTargetAlign);
9945b53394SDimitry Andric 
10045b53394SDimitry Andric   auto &baseLayout = getContext().getASTRecordLayout(baseDecl);
10145b53394SDimitry Andric   CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment();
10245b53394SDimitry Andric 
10345b53394SDimitry Andric   // If the class is properly aligned, assume the target offset is, too.
10445b53394SDimitry Andric   //
10545b53394SDimitry Andric   // This actually isn't necessarily the right thing to do --- if the
10645b53394SDimitry Andric   // class is a complete object, but it's only properly aligned for a
10745b53394SDimitry Andric   // base subobject, then the alignments of things relative to it are
10845b53394SDimitry Andric   // probably off as well.  (Note that this requires the alignment of
10945b53394SDimitry Andric   // the target to be greater than the NV alignment of the derived
11045b53394SDimitry Andric   // class.)
11145b53394SDimitry Andric   //
11245b53394SDimitry Andric   // However, our approach to this kind of under-alignment can only
11345b53394SDimitry Andric   // ever be best effort; after all, we're never going to propagate
11445b53394SDimitry Andric   // alignments through variables or parameters.  Note, in particular,
11545b53394SDimitry Andric   // that constructing a polymorphic type in an address that's less
11645b53394SDimitry Andric   // than pointer-aligned will generally trap in the constructor,
11745b53394SDimitry Andric   // unless we someday add some sort of attribute to change the
11845b53394SDimitry Andric   // assumed alignment of 'this'.  So our goal here is pretty much
11945b53394SDimitry Andric   // just to allow the user to explicitly say that a pointer is
1202b6b257fSDimitry Andric   // under-aligned and then safely access its fields and vtables.
12145b53394SDimitry Andric   if (actualBaseAlign >= expectedBaseAlign) {
12245b53394SDimitry Andric     return expectedTargetAlign;
12345b53394SDimitry Andric   }
12445b53394SDimitry Andric 
12545b53394SDimitry Andric   // Otherwise, we might be offset by an arbitrary multiple of the
12645b53394SDimitry Andric   // actual alignment.  The correct adjustment is to take the min of
12745b53394SDimitry Andric   // the two alignments.
12845b53394SDimitry Andric   return std::min(actualBaseAlign, expectedTargetAlign);
12945b53394SDimitry Andric }
13045b53394SDimitry Andric 
LoadCXXThisAddress()13145b53394SDimitry Andric Address CodeGenFunction::LoadCXXThisAddress() {
13245b53394SDimitry Andric   assert(CurFuncDecl && "loading 'this' without a func declaration?");
13377fc4c14SDimitry Andric   auto *MD = cast<CXXMethodDecl>(CurFuncDecl);
13445b53394SDimitry Andric 
13545b53394SDimitry Andric   // Lazily compute CXXThisAlignment.
13645b53394SDimitry Andric   if (CXXThisAlignment.isZero()) {
13745b53394SDimitry Andric     // Just use the best known alignment for the parent.
13845b53394SDimitry Andric     // TODO: if we're currently emitting a complete-object ctor/dtor,
13945b53394SDimitry Andric     // we can always use the complete-object alignment.
14077fc4c14SDimitry Andric     CXXThisAlignment = CGM.getClassPointerAlignment(MD->getParent());
14145b53394SDimitry Andric   }
14245b53394SDimitry Andric 
143ac9a064cSDimitry Andric   return makeNaturalAddressForPointer(
144ac9a064cSDimitry Andric       LoadCXXThis(), MD->getFunctionObjectParameterType(), CXXThisAlignment,
145ac9a064cSDimitry Andric       false, nullptr, nullptr, KnownNonNull);
14645b53394SDimitry Andric }
14745b53394SDimitry Andric 
14845b53394SDimitry Andric /// Emit the address of a field using a member data pointer.
14945b53394SDimitry Andric ///
15045b53394SDimitry Andric /// \param E Only used for emergency diagnostics
15145b53394SDimitry Andric Address
EmitCXXMemberDataPointerAddress(const Expr * E,Address base,llvm::Value * memberPtr,const MemberPointerType * memberPtrType,LValueBaseInfo * BaseInfo,TBAAAccessInfo * TBAAInfo)15245b53394SDimitry Andric CodeGenFunction::EmitCXXMemberDataPointerAddress(const Expr *E, Address base,
15345b53394SDimitry Andric                                                  llvm::Value *memberPtr,
15445b53394SDimitry Andric                                       const MemberPointerType *memberPtrType,
155461a67faSDimitry Andric                                                  LValueBaseInfo *BaseInfo,
156461a67faSDimitry Andric                                                  TBAAAccessInfo *TBAAInfo) {
15745b53394SDimitry Andric   // Ask the ABI to compute the actual address.
15845b53394SDimitry Andric   llvm::Value *ptr =
15945b53394SDimitry Andric     CGM.getCXXABI().EmitMemberDataPointerAddress(*this, E, base,
16045b53394SDimitry Andric                                                  memberPtr, memberPtrType);
16145b53394SDimitry Andric 
16245b53394SDimitry Andric   QualType memberType = memberPtrType->getPointeeType();
163cfca06d7SDimitry Andric   CharUnits memberAlign =
164cfca06d7SDimitry Andric       CGM.getNaturalTypeAlignment(memberType, BaseInfo, TBAAInfo);
16545b53394SDimitry Andric   memberAlign =
16645b53394SDimitry Andric     CGM.getDynamicOffsetAlignment(base.getAlignment(),
16745b53394SDimitry Andric                             memberPtrType->getClass()->getAsCXXRecordDecl(),
16845b53394SDimitry Andric                                   memberAlign);
169ecbca9f5SDimitry Andric   return Address(ptr, ConvertTypeForMem(memberPtrType->getPointeeType()),
170ecbca9f5SDimitry Andric                  memberAlign);
17145b53394SDimitry Andric }
17245b53394SDimitry Andric 
computeNonVirtualBaseClassOffset(const CXXRecordDecl * DerivedClass,CastExpr::path_const_iterator Start,CastExpr::path_const_iterator End)173c192b3dcSDimitry Andric CharUnits CodeGenModule::computeNonVirtualBaseClassOffset(
174c192b3dcSDimitry Andric     const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start,
1753d1dcd9bSDimitry Andric     CastExpr::path_const_iterator End) {
17601af97d3SDimitry Andric   CharUnits Offset = CharUnits::Zero();
1771569ce68SRoman Divacky 
178c192b3dcSDimitry Andric   const ASTContext &Context = getContext();
1790883ccd9SRoman Divacky   const CXXRecordDecl *RD = DerivedClass;
1800883ccd9SRoman Divacky 
1813d1dcd9bSDimitry Andric   for (CastExpr::path_const_iterator I = Start; I != End; ++I) {
1820883ccd9SRoman Divacky     const CXXBaseSpecifier *Base = *I;
1830883ccd9SRoman Divacky     assert(!Base->isVirtual() && "Should not see virtual bases here!");
1841569ce68SRoman Divacky 
1851569ce68SRoman Divacky     // Get the layout.
1860883ccd9SRoman Divacky     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
1871569ce68SRoman Divacky 
188519fc96cSDimitry Andric     const auto *BaseDecl =
189519fc96cSDimitry Andric         cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
1901569ce68SRoman Divacky 
1911569ce68SRoman Divacky     // Add the offset.
19201af97d3SDimitry Andric     Offset += Layout.getBaseClassOffset(BaseDecl);
1930883ccd9SRoman Divacky 
1940883ccd9SRoman Divacky     RD = BaseDecl;
1951569ce68SRoman Divacky   }
1961569ce68SRoman Divacky 
19701af97d3SDimitry Andric   return Offset;
1981569ce68SRoman Divacky }
1991569ce68SRoman Divacky 
2001569ce68SRoman Divacky llvm::Constant *
GetNonVirtualBaseClassOffset(const CXXRecordDecl * ClassDecl,CastExpr::path_const_iterator PathBegin,CastExpr::path_const_iterator PathEnd)2010883ccd9SRoman Divacky CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
2023d1dcd9bSDimitry Andric                                    CastExpr::path_const_iterator PathBegin,
2033d1dcd9bSDimitry Andric                                    CastExpr::path_const_iterator PathEnd) {
2043d1dcd9bSDimitry Andric   assert(PathBegin != PathEnd && "Base path should not be empty!");
2051569ce68SRoman Divacky 
20601af97d3SDimitry Andric   CharUnits Offset =
207c192b3dcSDimitry Andric       computeNonVirtualBaseClassOffset(ClassDecl, PathBegin, PathEnd);
20801af97d3SDimitry Andric   if (Offset.isZero())
2099f4dbff6SDimitry Andric     return nullptr;
2101569ce68SRoman Divacky 
21136981b17SDimitry Andric   llvm::Type *PtrDiffTy =
212e6b73279SDimitry Andric       getTypes().ConvertType(getContext().getPointerDiffType());
2131569ce68SRoman Divacky 
21401af97d3SDimitry Andric   return llvm::ConstantInt::get(PtrDiffTy, Offset.getQuantity());
2151569ce68SRoman Divacky }
2161569ce68SRoman Divacky 
2170883ccd9SRoman Divacky /// Gets the address of a direct base class within a complete object.
218ecb7e5c8SRoman Divacky /// This should only be used for (1) non-virtual bases or (2) virtual bases
219ecb7e5c8SRoman Divacky /// when the type is known to be complete (e.g. in complete destructors).
220ecb7e5c8SRoman Divacky ///
221ecb7e5c8SRoman Divacky /// The object pointed to by 'This' is assumed to be non-null.
22245b53394SDimitry Andric Address
GetAddressOfDirectBaseInCompleteClass(Address This,const CXXRecordDecl * Derived,const CXXRecordDecl * Base,bool BaseIsVirtual)22345b53394SDimitry Andric CodeGenFunction::GetAddressOfDirectBaseInCompleteClass(Address This,
224ecb7e5c8SRoman Divacky                                                    const CXXRecordDecl *Derived,
2250883ccd9SRoman Divacky                                                    const CXXRecordDecl *Base,
2260883ccd9SRoman Divacky                                                    bool BaseIsVirtual) {
227ecb7e5c8SRoman Divacky   // 'this' must be a pointer (in some address space) to Derived.
22845b53394SDimitry Andric   assert(This.getElementType() == ConvertType(Derived));
229ecb7e5c8SRoman Divacky 
230ecb7e5c8SRoman Divacky   // Compute the offset of the virtual base.
23101af97d3SDimitry Andric   CharUnits Offset;
232ecb7e5c8SRoman Divacky   const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived);
2330883ccd9SRoman Divacky   if (BaseIsVirtual)
23401af97d3SDimitry Andric     Offset = Layout.getVBaseClassOffset(Base);
235ecb7e5c8SRoman Divacky   else
23601af97d3SDimitry Andric     Offset = Layout.getBaseClassOffset(Base);
237ecb7e5c8SRoman Divacky 
238ecb7e5c8SRoman Divacky   // Shift and cast down to the base type.
239ecb7e5c8SRoman Divacky   // TODO: for complete types, this should be possible with a GEP.
24045b53394SDimitry Andric   Address V = This;
24145b53394SDimitry Andric   if (!Offset.isZero()) {
2427fa27ce4SDimitry Andric     V = V.withElementType(Int8Ty);
24345b53394SDimitry Andric     V = Builder.CreateConstInBoundsByteGEP(V, Offset);
244ecb7e5c8SRoman Divacky   }
2457fa27ce4SDimitry Andric   return V.withElementType(ConvertType(Base));
246ecb7e5c8SRoman Divacky }
247ecb7e5c8SRoman Divacky 
24845b53394SDimitry Andric static Address
ApplyNonVirtualAndVirtualOffset(CodeGenFunction & CGF,Address addr,CharUnits nonVirtualOffset,llvm::Value * virtualOffset,const CXXRecordDecl * derivedClass,const CXXRecordDecl * nearestVBase)24945b53394SDimitry Andric ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr,
25056d91b49SDimitry Andric                                 CharUnits nonVirtualOffset,
25145b53394SDimitry Andric                                 llvm::Value *virtualOffset,
25245b53394SDimitry Andric                                 const CXXRecordDecl *derivedClass,
25345b53394SDimitry Andric                                 const CXXRecordDecl *nearestVBase) {
25456d91b49SDimitry Andric   // Assert that we have something to do.
2559f4dbff6SDimitry Andric   assert(!nonVirtualOffset.isZero() || virtualOffset != nullptr);
2560883ccd9SRoman Divacky 
25756d91b49SDimitry Andric   // Compute the offset from the static and dynamic components.
25856d91b49SDimitry Andric   llvm::Value *baseOffset;
25956d91b49SDimitry Andric   if (!nonVirtualOffset.isZero()) {
260cfca06d7SDimitry Andric     llvm::Type *OffsetType =
261cfca06d7SDimitry Andric         (CGF.CGM.getTarget().getCXXABI().isItaniumFamily() &&
262cfca06d7SDimitry Andric          CGF.CGM.getItaniumVTableContext().isRelativeLayout())
263cfca06d7SDimitry Andric             ? CGF.Int32Ty
264cfca06d7SDimitry Andric             : CGF.PtrDiffTy;
265cfca06d7SDimitry Andric     baseOffset =
266cfca06d7SDimitry Andric         llvm::ConstantInt::get(OffsetType, nonVirtualOffset.getQuantity());
26756d91b49SDimitry Andric     if (virtualOffset) {
26856d91b49SDimitry Andric       baseOffset = CGF.Builder.CreateAdd(virtualOffset, baseOffset);
26956d91b49SDimitry Andric     }
27056d91b49SDimitry Andric   } else {
27156d91b49SDimitry Andric     baseOffset = virtualOffset;
27256d91b49SDimitry Andric   }
2730883ccd9SRoman Divacky 
2740883ccd9SRoman Divacky   // Apply the base offset.
275ac9a064cSDimitry Andric   llvm::Value *ptr = addr.emitRawPointer(CGF);
276344a3780SDimitry Andric   ptr = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, ptr, baseOffset, "add.ptr");
27745b53394SDimitry Andric 
27845b53394SDimitry Andric   // If we have a virtual component, the alignment of the result will
27945b53394SDimitry Andric   // be relative only to the known alignment of that vbase.
28045b53394SDimitry Andric   CharUnits alignment;
28145b53394SDimitry Andric   if (virtualOffset) {
28245b53394SDimitry Andric     assert(nearestVBase && "virtual offset without vbase?");
28345b53394SDimitry Andric     alignment = CGF.CGM.getVBaseAlignment(addr.getAlignment(),
28445b53394SDimitry Andric                                           derivedClass, nearestVBase);
28545b53394SDimitry Andric   } else {
28645b53394SDimitry Andric     alignment = addr.getAlignment();
28745b53394SDimitry Andric   }
28845b53394SDimitry Andric   alignment = alignment.alignmentAtOffset(nonVirtualOffset);
28945b53394SDimitry Andric 
29077fc4c14SDimitry Andric   return Address(ptr, CGF.Int8Ty, alignment);
2910883ccd9SRoman Divacky }
2920883ccd9SRoman Divacky 
GetAddressOfBaseClass(Address Value,const CXXRecordDecl * Derived,CastExpr::path_const_iterator PathBegin,CastExpr::path_const_iterator PathEnd,bool NullCheckValue,SourceLocation Loc)29345b53394SDimitry Andric Address CodeGenFunction::GetAddressOfBaseClass(
29445b53394SDimitry Andric     Address Value, const CXXRecordDecl *Derived,
2953d1dcd9bSDimitry Andric     CastExpr::path_const_iterator PathBegin,
29606d4ba38SDimitry Andric     CastExpr::path_const_iterator PathEnd, bool NullCheckValue,
29706d4ba38SDimitry Andric     SourceLocation Loc) {
2983d1dcd9bSDimitry Andric   assert(PathBegin != PathEnd && "Base path should not be empty!");
2991569ce68SRoman Divacky 
3003d1dcd9bSDimitry Andric   CastExpr::path_const_iterator Start = PathBegin;
3019f4dbff6SDimitry Andric   const CXXRecordDecl *VBase = nullptr;
3020883ccd9SRoman Divacky 
30356d91b49SDimitry Andric   // Sema has done some convenient canonicalization here: if the
30456d91b49SDimitry Andric   // access path involved any virtual steps, the conversion path will
30556d91b49SDimitry Andric   // *start* with a step down to the correct virtual base subobject,
30656d91b49SDimitry Andric   // and hence will not require any further steps.
3070883ccd9SRoman Divacky   if ((*Start)->isVirtual()) {
308519fc96cSDimitry Andric     VBase = cast<CXXRecordDecl>(
309519fc96cSDimitry Andric         (*Start)->getType()->castAs<RecordType>()->getDecl());
3100883ccd9SRoman Divacky     ++Start;
311ecb7e5c8SRoman Divacky   }
312ecb7e5c8SRoman Divacky 
31356d91b49SDimitry Andric   // Compute the static offset of the ultimate destination within its
31456d91b49SDimitry Andric   // allocating subobject (the virtual base, if there is one, or else
31556d91b49SDimitry Andric   // the "complete" object that we see).
316c192b3dcSDimitry Andric   CharUnits NonVirtualOffset = CGM.computeNonVirtualBaseClassOffset(
317c192b3dcSDimitry Andric       VBase ? VBase : Derived, Start, PathEnd);
318ecb7e5c8SRoman Divacky 
31956d91b49SDimitry Andric   // If there's a virtual step, we can sometimes "devirtualize" it.
32056d91b49SDimitry Andric   // For now, that's limited to when the derived type is final.
32156d91b49SDimitry Andric   // TODO: "devirtualize" this for accesses to known-complete objects.
32256d91b49SDimitry Andric   if (VBase && Derived->hasAttr<FinalAttr>()) {
32356d91b49SDimitry Andric     const ASTRecordLayout &layout = getContext().getASTRecordLayout(Derived);
32456d91b49SDimitry Andric     CharUnits vBaseOffset = layout.getVBaseClassOffset(VBase);
32556d91b49SDimitry Andric     NonVirtualOffset += vBaseOffset;
3269f4dbff6SDimitry Andric     VBase = nullptr; // we no longer have a virtual step
32756d91b49SDimitry Andric   }
32856d91b49SDimitry Andric 
3290883ccd9SRoman Divacky   // Get the base pointer type.
33077fc4c14SDimitry Andric   llvm::Type *BaseValueTy = ConvertType((PathEnd[-1])->getType());
3317fa27ce4SDimitry Andric   llvm::Type *PtrTy = llvm::PointerType::get(
3327fa27ce4SDimitry Andric       CGM.getLLVMContext(), Value.getType()->getPointerAddressSpace());
3330883ccd9SRoman Divacky 
33406d4ba38SDimitry Andric   QualType DerivedTy = getContext().getRecordType(Derived);
33545b53394SDimitry Andric   CharUnits DerivedAlign = CGM.getClassPointerAlignment(Derived);
33606d4ba38SDimitry Andric 
33756d91b49SDimitry Andric   // If the static offset is zero and we don't have a virtual step,
33856d91b49SDimitry Andric   // just do a bitcast; null checks are unnecessary.
33901af97d3SDimitry Andric   if (NonVirtualOffset.isZero() && !VBase) {
34006d4ba38SDimitry Andric     if (sanitizePerformTypeCheck()) {
3417442d6faSDimitry Andric       SanitizerSet SkippedChecks;
3427442d6faSDimitry Andric       SkippedChecks.set(SanitizerKind::Null, !NullCheckValue);
343ac9a064cSDimitry Andric       EmitTypeCheck(TCK_Upcast, Loc, Value.emitRawPointer(*this), DerivedTy,
344ac9a064cSDimitry Andric                     DerivedAlign, SkippedChecks);
34506d4ba38SDimitry Andric     }
3467fa27ce4SDimitry Andric     return Value.withElementType(BaseValueTy);
3471569ce68SRoman Divacky   }
3481569ce68SRoman Divacky 
3499f4dbff6SDimitry Andric   llvm::BasicBlock *origBB = nullptr;
3509f4dbff6SDimitry Andric   llvm::BasicBlock *endBB = nullptr;
3511569ce68SRoman Divacky 
35256d91b49SDimitry Andric   // Skip over the offset (and the vtable load) if we're supposed to
35356d91b49SDimitry Andric   // null-check the pointer.
3541569ce68SRoman Divacky   if (NullCheckValue) {
35556d91b49SDimitry Andric     origBB = Builder.GetInsertBlock();
35656d91b49SDimitry Andric     llvm::BasicBlock *notNullBB = createBasicBlock("cast.notnull");
35756d91b49SDimitry Andric     endBB = createBasicBlock("cast.end");
3581569ce68SRoman Divacky 
359ac9a064cSDimitry Andric     llvm::Value *isNull = Builder.CreateIsNull(Value);
36056d91b49SDimitry Andric     Builder.CreateCondBr(isNull, endBB, notNullBB);
36156d91b49SDimitry Andric     EmitBlock(notNullBB);
3621569ce68SRoman Divacky   }
3631569ce68SRoman Divacky 
36406d4ba38SDimitry Andric   if (sanitizePerformTypeCheck()) {
3657442d6faSDimitry Andric     SanitizerSet SkippedChecks;
3667442d6faSDimitry Andric     SkippedChecks.set(SanitizerKind::Null, true);
36745b53394SDimitry Andric     EmitTypeCheck(VBase ? TCK_UpcastToVirtualBase : TCK_Upcast, Loc,
368ac9a064cSDimitry Andric                   Value.emitRawPointer(*this), DerivedTy, DerivedAlign,
369ac9a064cSDimitry Andric                   SkippedChecks);
37006d4ba38SDimitry Andric   }
37106d4ba38SDimitry Andric 
37256d91b49SDimitry Andric   // Compute the virtual offset.
3739f4dbff6SDimitry Andric   llvm::Value *VirtualOffset = nullptr;
374bca07a45SDimitry Andric   if (VBase) {
375bfef3995SDimitry Andric     VirtualOffset =
376bfef3995SDimitry Andric         CGM.getCXXABI().GetVirtualBaseClassOffset(*this, Value, Derived, VBase);
377bca07a45SDimitry Andric   }
3781569ce68SRoman Divacky 
37956d91b49SDimitry Andric   // Apply both offsets.
38045b53394SDimitry Andric   Value = ApplyNonVirtualAndVirtualOffset(*this, Value, NonVirtualOffset,
38145b53394SDimitry Andric                                           VirtualOffset, Derived, VBase);
3821569ce68SRoman Divacky 
38356d91b49SDimitry Andric   // Cast to the destination type.
3847fa27ce4SDimitry Andric   Value = Value.withElementType(BaseValueTy);
3851569ce68SRoman Divacky 
38656d91b49SDimitry Andric   // Build a phi if we needed a null check.
3871569ce68SRoman Divacky   if (NullCheckValue) {
38856d91b49SDimitry Andric     llvm::BasicBlock *notNullBB = Builder.GetInsertBlock();
38956d91b49SDimitry Andric     Builder.CreateBr(endBB);
39056d91b49SDimitry Andric     EmitBlock(endBB);
3911569ce68SRoman Divacky 
3927fa27ce4SDimitry Andric     llvm::PHINode *PHI = Builder.CreatePHI(PtrTy, 2, "cast.result");
393ac9a064cSDimitry Andric     PHI->addIncoming(Value.emitRawPointer(*this), notNullBB);
3947fa27ce4SDimitry Andric     PHI->addIncoming(llvm::Constant::getNullValue(PtrTy), origBB);
3957fa27ce4SDimitry Andric     Value = Value.withPointer(PHI, NotKnownNonNull);
3961569ce68SRoman Divacky   }
3971569ce68SRoman Divacky 
3981569ce68SRoman Divacky   return Value;
3991569ce68SRoman Divacky }
4001569ce68SRoman Divacky 
40145b53394SDimitry Andric Address
GetAddressOfDerivedClass(Address BaseAddr,const CXXRecordDecl * Derived,CastExpr::path_const_iterator PathBegin,CastExpr::path_const_iterator PathEnd,bool NullCheckValue)40245b53394SDimitry Andric CodeGenFunction::GetAddressOfDerivedClass(Address BaseAddr,
4030883ccd9SRoman Divacky                                           const CXXRecordDecl *Derived,
4043d1dcd9bSDimitry Andric                                         CastExpr::path_const_iterator PathBegin,
4053d1dcd9bSDimitry Andric                                           CastExpr::path_const_iterator PathEnd,
4061569ce68SRoman Divacky                                           bool NullCheckValue) {
4073d1dcd9bSDimitry Andric   assert(PathBegin != PathEnd && "Base path should not be empty!");
4080883ccd9SRoman Divacky 
4091569ce68SRoman Divacky   QualType DerivedTy =
4100883ccd9SRoman Divacky       getContext().getCanonicalType(getContext().getTagDeclType(Derived));
41177fc4c14SDimitry Andric   llvm::Type *DerivedValueTy = ConvertType(DerivedTy);
4121569ce68SRoman Divacky 
413ecb7e5c8SRoman Divacky   llvm::Value *NonVirtualOffset =
4143d1dcd9bSDimitry Andric     CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd);
415ecb7e5c8SRoman Divacky 
416ecb7e5c8SRoman Divacky   if (!NonVirtualOffset) {
417ecb7e5c8SRoman Divacky     // No offset, we can just cast back.
4187fa27ce4SDimitry Andric     return BaseAddr.withElementType(DerivedValueTy);
419ecb7e5c8SRoman Divacky   }
420ecb7e5c8SRoman Divacky 
4219f4dbff6SDimitry Andric   llvm::BasicBlock *CastNull = nullptr;
4229f4dbff6SDimitry Andric   llvm::BasicBlock *CastNotNull = nullptr;
4239f4dbff6SDimitry Andric   llvm::BasicBlock *CastEnd = nullptr;
4241569ce68SRoman Divacky 
4251569ce68SRoman Divacky   if (NullCheckValue) {
4261569ce68SRoman Divacky     CastNull = createBasicBlock("cast.null");
4271569ce68SRoman Divacky     CastNotNull = createBasicBlock("cast.notnull");
4281569ce68SRoman Divacky     CastEnd = createBasicBlock("cast.end");
4291569ce68SRoman Divacky 
430ac9a064cSDimitry Andric     llvm::Value *IsNull = Builder.CreateIsNull(BaseAddr);
4311569ce68SRoman Divacky     Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
4321569ce68SRoman Divacky     EmitBlock(CastNotNull);
4331569ce68SRoman Divacky   }
4341569ce68SRoman Divacky 
4351569ce68SRoman Divacky   // Apply the offset.
436ac9a064cSDimitry Andric   Address Addr = BaseAddr.withElementType(Int8Ty);
437ac9a064cSDimitry Andric   Addr = Builder.CreateInBoundsGEP(
438ac9a064cSDimitry Andric       Addr, Builder.CreateNeg(NonVirtualOffset), Int8Ty,
439ac9a064cSDimitry Andric       CGM.getClassPointerAlignment(Derived), "sub.ptr");
440ac9a064cSDimitry Andric 
441ac9a064cSDimitry Andric   // Just cast.
442ac9a064cSDimitry Andric   Addr = Addr.withElementType(DerivedValueTy);
443ecb7e5c8SRoman Divacky 
44445b53394SDimitry Andric   // Produce a PHI if we had a null-check.
4451569ce68SRoman Divacky   if (NullCheckValue) {
4461569ce68SRoman Divacky     Builder.CreateBr(CastEnd);
4471569ce68SRoman Divacky     EmitBlock(CastNull);
4481569ce68SRoman Divacky     Builder.CreateBr(CastEnd);
4491569ce68SRoman Divacky     EmitBlock(CastEnd);
4501569ce68SRoman Divacky 
451ac9a064cSDimitry Andric     llvm::Value *Value = Addr.emitRawPointer(*this);
45201af97d3SDimitry Andric     llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2);
4531569ce68SRoman Divacky     PHI->addIncoming(Value, CastNotNull);
45445b53394SDimitry Andric     PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull);
455ac9a064cSDimitry Andric     return Address(PHI, Addr.getElementType(),
456ac9a064cSDimitry Andric                    CGM.getClassPointerAlignment(Derived));
4571569ce68SRoman Divacky   }
4581569ce68SRoman Divacky 
459ac9a064cSDimitry Andric   return Addr;
4601569ce68SRoman Divacky }
461abe15e55SRoman Divacky 
GetVTTParameter(GlobalDecl GD,bool ForVirtualBase,bool Delegating)462809500fcSDimitry Andric llvm::Value *CodeGenFunction::GetVTTParameter(GlobalDecl GD,
463809500fcSDimitry Andric                                               bool ForVirtualBase,
464809500fcSDimitry Andric                                               bool Delegating) {
465bfef3995SDimitry Andric   if (!CGM.getCXXABI().NeedsVTTParameter(GD)) {
466ee791ddeSRoman Divacky     // This constructor/destructor does not need a VTT parameter.
4679f4dbff6SDimitry Andric     return nullptr;
468ee791ddeSRoman Divacky   }
469ee791ddeSRoman Divacky 
4706a037251SDimitry Andric   const CXXRecordDecl *RD = cast<CXXMethodDecl>(CurCodeDecl)->getParent();
471ee791ddeSRoman Divacky   const CXXRecordDecl *Base = cast<CXXMethodDecl>(GD.getDecl())->getParent();
472ee791ddeSRoman Divacky 
47379ade4e0SRoman Divacky   uint64_t SubVTTIndex;
47479ade4e0SRoman Divacky 
475809500fcSDimitry Andric   if (Delegating) {
476809500fcSDimitry Andric     // If this is a delegating constructor call, just load the VTT.
477809500fcSDimitry Andric     return LoadCXXVTT();
478809500fcSDimitry Andric   } else if (RD == Base) {
47979ade4e0SRoman Divacky     // If the record matches the base, this is the complete ctor/dtor
48079ade4e0SRoman Divacky     // variant calling the base variant in a class with virtual bases.
481bfef3995SDimitry Andric     assert(!CGM.getCXXABI().NeedsVTTParameter(CurGD) &&
48279ade4e0SRoman Divacky            "doing no-op VTT offset in base dtor/ctor?");
4830883ccd9SRoman Divacky     assert(!ForVirtualBase && "Can't have same class as virtual base!");
48479ade4e0SRoman Divacky     SubVTTIndex = 0;
48579ade4e0SRoman Divacky   } else {
486809500fcSDimitry Andric     const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
48701af97d3SDimitry Andric     CharUnits BaseOffset = ForVirtualBase ?
48801af97d3SDimitry Andric       Layout.getVBaseClassOffset(Base) :
48901af97d3SDimitry Andric       Layout.getBaseClassOffset(Base);
4900883ccd9SRoman Divacky 
4910883ccd9SRoman Divacky     SubVTTIndex =
492809500fcSDimitry Andric       CGM.getVTables().getSubVTTIndex(RD, BaseSubobject(Base, BaseOffset));
493ee791ddeSRoman Divacky     assert(SubVTTIndex != 0 && "Sub-VTT index must be greater than zero!");
49479ade4e0SRoman Divacky   }
495ee791ddeSRoman Divacky 
496bfef3995SDimitry Andric   if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {
497ee791ddeSRoman Divacky     // A VTT parameter was passed to the constructor, use it.
498344a3780SDimitry Andric     llvm::Value *VTT = LoadCXXVTT();
499344a3780SDimitry Andric     return Builder.CreateConstInBoundsGEP1_64(VoidPtrTy, VTT, SubVTTIndex);
500ee791ddeSRoman Divacky   } else {
501ee791ddeSRoman Divacky     // We're the complete constructor, so get the VTT by name.
502344a3780SDimitry Andric     llvm::GlobalValue *VTT = CGM.getVTables().GetAddrOfVTT(RD);
503344a3780SDimitry Andric     return Builder.CreateConstInBoundsGEP2_64(
504344a3780SDimitry Andric         VTT->getValueType(), VTT, 0, SubVTTIndex);
505ee791ddeSRoman Divacky   }
506ee791ddeSRoman Divacky }
507ee791ddeSRoman Divacky 
5083d1dcd9bSDimitry Andric namespace {
5093d1dcd9bSDimitry Andric   /// Call the destructor for a direct base class.
51045b53394SDimitry Andric   struct CallBaseDtor final : EHScopeStack::Cleanup {
5113d1dcd9bSDimitry Andric     const CXXRecordDecl *BaseClass;
5123d1dcd9bSDimitry Andric     bool BaseIsVirtual;
CallBaseDtor__anonf1d54d130111::CallBaseDtor5133d1dcd9bSDimitry Andric     CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual)
5143d1dcd9bSDimitry Andric       : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {}
5153d1dcd9bSDimitry Andric 
Emit__anonf1d54d130111::CallBaseDtor5169f4dbff6SDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
5173d1dcd9bSDimitry Andric       const CXXRecordDecl *DerivedClass =
5183d1dcd9bSDimitry Andric         cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent();
5193d1dcd9bSDimitry Andric 
5203d1dcd9bSDimitry Andric       const CXXDestructorDecl *D = BaseClass->getDestructor();
52122989816SDimitry Andric       // We are already inside a destructor, so presumably the object being
52222989816SDimitry Andric       // destroyed should have the expected type.
523b1c73532SDimitry Andric       QualType ThisTy = D->getFunctionObjectParameterType();
52445b53394SDimitry Andric       Address Addr =
52545b53394SDimitry Andric         CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThisAddress(),
5263d1dcd9bSDimitry Andric                                                   DerivedClass, BaseClass,
5273d1dcd9bSDimitry Andric                                                   BaseIsVirtual);
528809500fcSDimitry Andric       CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual,
52922989816SDimitry Andric                                 /*Delegating=*/false, Addr, ThisTy);
5303d1dcd9bSDimitry Andric     }
5313d1dcd9bSDimitry Andric   };
532bca07a45SDimitry Andric 
533bca07a45SDimitry Andric   /// A visitor which checks whether an initializer uses 'this' in a
534bca07a45SDimitry Andric   /// way which requires the vtable to be properly set.
5352e645aa5SDimitry Andric   struct DynamicThisUseChecker : ConstEvaluatedExprVisitor<DynamicThisUseChecker> {
5362e645aa5SDimitry Andric     typedef ConstEvaluatedExprVisitor<DynamicThisUseChecker> super;
537bca07a45SDimitry Andric 
538bca07a45SDimitry Andric     bool UsesThis;
539bca07a45SDimitry Andric 
DynamicThisUseChecker__anonf1d54d130111::DynamicThisUseChecker5402e645aa5SDimitry Andric     DynamicThisUseChecker(const ASTContext &C) : super(C), UsesThis(false) {}
541bca07a45SDimitry Andric 
542bca07a45SDimitry Andric     // Black-list all explicit and implicit references to 'this'.
543bca07a45SDimitry Andric     //
544bca07a45SDimitry Andric     // Do we need to worry about external references to 'this' derived
545bca07a45SDimitry Andric     // from arbitrary code?  If so, then anything which runs arbitrary
546bca07a45SDimitry Andric     // external code might potentially access the vtable.
VisitCXXThisExpr__anonf1d54d130111::DynamicThisUseChecker5472e645aa5SDimitry Andric     void VisitCXXThisExpr(const CXXThisExpr *E) { UsesThis = true; }
548bca07a45SDimitry Andric   };
54945b53394SDimitry Andric } // end anonymous namespace
550bca07a45SDimitry Andric 
BaseInitializerUsesThis(ASTContext & C,const Expr * Init)551bca07a45SDimitry Andric static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init) {
552bca07a45SDimitry Andric   DynamicThisUseChecker Checker(C);
5532e645aa5SDimitry Andric   Checker.Visit(Init);
554bca07a45SDimitry Andric   return Checker.UsesThis;
5553d1dcd9bSDimitry Andric }
5563d1dcd9bSDimitry Andric 
EmitBaseInitializer(CodeGenFunction & CGF,const CXXRecordDecl * ClassDecl,CXXCtorInitializer * BaseInit)557abe15e55SRoman Divacky static void EmitBaseInitializer(CodeGenFunction &CGF,
558abe15e55SRoman Divacky                                 const CXXRecordDecl *ClassDecl,
55922989816SDimitry Andric                                 CXXCtorInitializer *BaseInit) {
560abe15e55SRoman Divacky   assert(BaseInit->isBaseInitializer() &&
561abe15e55SRoman Divacky          "Must have base initializer!");
562abe15e55SRoman Divacky 
56345b53394SDimitry Andric   Address ThisPtr = CGF.LoadCXXThisAddress();
564abe15e55SRoman Divacky 
565abe15e55SRoman Divacky   const Type *BaseType = BaseInit->getBaseClass();
566519fc96cSDimitry Andric   const auto *BaseClassDecl =
567519fc96cSDimitry Andric       cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl());
568abe15e55SRoman Divacky 
5690883ccd9SRoman Divacky   bool isBaseVirtual = BaseInit->isBaseVirtual();
570abe15e55SRoman Divacky 
571bca07a45SDimitry Andric   // If the initializer for the base (other than the constructor
572bca07a45SDimitry Andric   // itself) accesses 'this' in any way, we need to initialize the
573bca07a45SDimitry Andric   // vtables.
574bca07a45SDimitry Andric   if (BaseInitializerUsesThis(CGF.getContext(), BaseInit->getInit()))
575bca07a45SDimitry Andric     CGF.InitializeVTablePointers(ClassDecl);
576bca07a45SDimitry Andric 
577ecb7e5c8SRoman Divacky   // We can pretend to be a complete class because it only matters for
578ecb7e5c8SRoman Divacky   // virtual bases, and we only do virtual bases for complete ctors.
57945b53394SDimitry Andric   Address V =
5800883ccd9SRoman Divacky     CGF.GetAddressOfDirectBaseInCompleteClass(ThisPtr, ClassDecl,
5810883ccd9SRoman Divacky                                               BaseClassDecl,
5823d1dcd9bSDimitry Andric                                               isBaseVirtual);
58336981b17SDimitry Andric   AggValueSlot AggSlot =
58448675466SDimitry Andric       AggValueSlot::forAddr(
58548675466SDimitry Andric           V, Qualifiers(),
58636981b17SDimitry Andric           AggValueSlot::IsDestructed,
58736981b17SDimitry Andric           AggValueSlot::DoesNotNeedGCBarriers,
58848675466SDimitry Andric           AggValueSlot::IsNotAliased,
58922989816SDimitry Andric           CGF.getOverlapForBaseInit(ClassDecl, BaseClassDecl, isBaseVirtual));
590ecb7e5c8SRoman Divacky 
591bca07a45SDimitry Andric   CGF.EmitAggExpr(BaseInit->getInit(), AggSlot);
592bca07a45SDimitry Andric 
593dbe13110SDimitry Andric   if (CGF.CGM.getLangOpts().Exceptions &&
594bca07a45SDimitry Andric       !BaseClassDecl->hasTrivialDestructor())
5953d1dcd9bSDimitry Andric     CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl,
5963d1dcd9bSDimitry Andric                                           isBaseVirtual);
597abe15e55SRoman Divacky }
598abe15e55SRoman Divacky 
isMemcpyEquivalentSpecialMember(const CXXMethodDecl * D)5995e20cdd8SDimitry Andric static bool isMemcpyEquivalentSpecialMember(const CXXMethodDecl *D) {
6005e20cdd8SDimitry Andric   auto *CD = dyn_cast<CXXConstructorDecl>(D);
6015e20cdd8SDimitry Andric   if (!(CD && CD->isCopyOrMoveConstructor()) &&
6025e20cdd8SDimitry Andric       !D->isCopyAssignmentOperator() && !D->isMoveAssignmentOperator())
6035e20cdd8SDimitry Andric     return false;
6045e20cdd8SDimitry Andric 
6055e20cdd8SDimitry Andric   // We can emit a memcpy for a trivial copy or move constructor/assignment.
6065e20cdd8SDimitry Andric   if (D->isTrivial() && !D->getParent()->mayInsertExtraPadding())
6075e20cdd8SDimitry Andric     return true;
6085e20cdd8SDimitry Andric 
6095e20cdd8SDimitry Andric   // We *must* emit a memcpy for a defaulted union copy or move op.
6105e20cdd8SDimitry Andric   if (D->getParent()->isUnion() && D->isDefaulted())
6115e20cdd8SDimitry Andric     return true;
6125e20cdd8SDimitry Andric 
6135e20cdd8SDimitry Andric   return false;
6145e20cdd8SDimitry Andric }
6155e20cdd8SDimitry Andric 
EmitLValueForAnyFieldInitialization(CodeGenFunction & CGF,CXXCtorInitializer * MemberInit,LValue & LHS)61651ece4aaSDimitry Andric static void EmitLValueForAnyFieldInitialization(CodeGenFunction &CGF,
61751ece4aaSDimitry Andric                                                 CXXCtorInitializer *MemberInit,
61851ece4aaSDimitry Andric                                                 LValue &LHS) {
61951ece4aaSDimitry Andric   FieldDecl *Field = MemberInit->getAnyMember();
62051ece4aaSDimitry Andric   if (MemberInit->isIndirectMemberInitializer()) {
62151ece4aaSDimitry Andric     // If we are initializing an anonymous union field, drill down to the field.
62251ece4aaSDimitry Andric     IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember();
62351ece4aaSDimitry Andric     for (const auto *I : IndirectField->chain())
62451ece4aaSDimitry Andric       LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(I));
62551ece4aaSDimitry Andric   } else {
62651ece4aaSDimitry Andric     LHS = CGF.EmitLValueForFieldInitialization(LHS, Field);
62751ece4aaSDimitry Andric   }
62851ece4aaSDimitry Andric }
62951ece4aaSDimitry Andric 
EmitMemberInitializer(CodeGenFunction & CGF,const CXXRecordDecl * ClassDecl,CXXCtorInitializer * MemberInit,const CXXConstructorDecl * Constructor,FunctionArgList & Args)630abe15e55SRoman Divacky static void EmitMemberInitializer(CodeGenFunction &CGF,
631abe15e55SRoman Divacky                                   const CXXRecordDecl *ClassDecl,
632bca07a45SDimitry Andric                                   CXXCtorInitializer *MemberInit,
633d7279c4cSRoman Divacky                                   const CXXConstructorDecl *Constructor,
634d7279c4cSRoman Divacky                                   FunctionArgList &Args) {
635ec12bbe3SDimitry Andric   ApplyDebugLocation Loc(CGF, MemberInit->getSourceLocation());
636bca07a45SDimitry Andric   assert(MemberInit->isAnyMemberInitializer() &&
637abe15e55SRoman Divacky          "Must have member initializer!");
63829cafa66SDimitry Andric   assert(MemberInit->getInit() && "Must have initializer!");
639abe15e55SRoman Divacky 
640abe15e55SRoman Divacky   // non-static data member initializers.
641bca07a45SDimitry Andric   FieldDecl *Field = MemberInit->getAnyMember();
642dbe13110SDimitry Andric   QualType FieldType = Field->getType();
643abe15e55SRoman Divacky 
644abe15e55SRoman Divacky   llvm::Value *ThisPtr = CGF.LoadCXXThis();
6456b9a6e39SDimitry Andric   QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
64648675466SDimitry Andric   LValue LHS;
64748675466SDimitry Andric 
64848675466SDimitry Andric   // If a base constructor is being emitted, create an LValue that has the
64948675466SDimitry Andric   // non-virtual alignment.
65048675466SDimitry Andric   if (CGF.CurGD.getCtorType() == Ctor_Base)
65148675466SDimitry Andric     LHS = CGF.MakeNaturalAlignPointeeAddrLValue(ThisPtr, RecordTy);
65248675466SDimitry Andric   else
65348675466SDimitry Andric     LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy);
654abe15e55SRoman Divacky 
65551ece4aaSDimitry Andric   EmitLValueForAnyFieldInitialization(CGF, MemberInit, LHS);
656abe15e55SRoman Divacky 
657dbe13110SDimitry Andric   // Special case: if we are in a copy or move constructor, and we are copying
658dbe13110SDimitry Andric   // an array of PODs or classes with trivial copy constructors, ignore the
659dbe13110SDimitry Andric   // AST and perform the copy we know is equivalent.
660dbe13110SDimitry Andric   // FIXME: This is hacky at best... if we had a bit more explicit information
661dbe13110SDimitry Andric   // in the AST, we could generalize it more easily.
662d7279c4cSRoman Divacky   const ConstantArrayType *Array
663d7279c4cSRoman Divacky     = CGF.getContext().getAsConstantArrayType(FieldType);
664bfef3995SDimitry Andric   if (Array && Constructor->isDefaulted() &&
66536981b17SDimitry Andric       Constructor->isCopyOrMoveConstructor()) {
666d7279c4cSRoman Divacky     QualType BaseElementTy = CGF.getContext().getBaseElementType(Array);
66713cc256eSDimitry Andric     CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit());
668180abc3dSDimitry Andric     if (BaseElementTy.isPODType(CGF.getContext()) ||
6695e20cdd8SDimitry Andric         (CE && isMemcpyEquivalentSpecialMember(CE->getConstructor()))) {
67006d4ba38SDimitry Andric       unsigned SrcArgIndex =
67106d4ba38SDimitry Andric           CGF.CGM.getCXXABI().getSrcArgforCopyCtor(Constructor, Args);
672d7279c4cSRoman Divacky       llvm::Value *SrcPtr
67301af97d3SDimitry Andric         = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(Args[SrcArgIndex]));
6746b9a6e39SDimitry Andric       LValue ThisRHSLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy);
6756b9a6e39SDimitry Andric       LValue Src = CGF.EmitLValueForFieldInitialization(ThisRHSLV, Field);
676d7279c4cSRoman Divacky 
677d7279c4cSRoman Divacky       // Copy the aggregate.
67822989816SDimitry Andric       CGF.EmitAggregateCopy(LHS, Src, FieldType, CGF.getOverlapForFieldInit(Field),
679d7279c4cSRoman Divacky                             LHS.isVolatileQualified());
68051ece4aaSDimitry Andric       // Ensure that we destroy the objects if an exception is thrown later in
68151ece4aaSDimitry Andric       // the constructor.
68251ece4aaSDimitry Andric       QualType::DestructionKind dtorKind = FieldType.isDestructedType();
68351ece4aaSDimitry Andric       if (CGF.needsEHCleanup(dtorKind))
684ac9a064cSDimitry Andric         CGF.pushEHDestroy(dtorKind, LHS.getAddress(), FieldType);
685d7279c4cSRoman Divacky       return;
686d7279c4cSRoman Divacky     }
687d7279c4cSRoman Divacky   }
688d7279c4cSRoman Divacky 
689bab175ecSDimitry Andric   CGF.EmitInitializerForField(Field, LHS, MemberInit->getInit());
690dbe13110SDimitry Andric }
691ecb7e5c8SRoman Divacky 
EmitInitializerForField(FieldDecl * Field,LValue LHS,Expr * Init)69245b53394SDimitry Andric void CodeGenFunction::EmitInitializerForField(FieldDecl *Field, LValue LHS,
693bab175ecSDimitry Andric                                               Expr *Init) {
694dbe13110SDimitry Andric   QualType FieldType = Field->getType();
695809500fcSDimitry Andric   switch (getEvaluationKind(FieldType)) {
696809500fcSDimitry Andric   case TEK_Scalar:
697dbe13110SDimitry Andric     if (LHS.isSimple()) {
698dbe13110SDimitry Andric       EmitExprAsInit(Init, Field, LHS, false);
699dbe13110SDimitry Andric     } else {
700dbe13110SDimitry Andric       RValue RHS = RValue::get(EmitScalarExpr(Init));
701dbe13110SDimitry Andric       EmitStoreThroughLValue(RHS, LHS);
702dbe13110SDimitry Andric     }
703809500fcSDimitry Andric     break;
704809500fcSDimitry Andric   case TEK_Complex:
705809500fcSDimitry Andric     EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true);
706809500fcSDimitry Andric     break;
707809500fcSDimitry Andric   case TEK_Aggregate: {
708706b4fc4SDimitry Andric     AggValueSlot Slot = AggValueSlot::forLValue(
709ac9a064cSDimitry Andric         LHS, AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers,
710ac9a064cSDimitry Andric         AggValueSlot::IsNotAliased, getOverlapForFieldInit(Field),
711ac9a064cSDimitry Andric         AggValueSlot::IsNotZeroed,
712c7e70c43SDimitry Andric         // Checks are made by the code that calls constructor.
713c7e70c43SDimitry Andric         AggValueSlot::IsSanitizerChecked);
714bab175ecSDimitry Andric     EmitAggExpr(Init, Slot);
715bab175ecSDimitry Andric     break;
716abe15e55SRoman Divacky   }
717abe15e55SRoman Divacky   }
718abe15e55SRoman Divacky 
719809500fcSDimitry Andric   // Ensure that we destroy this object if an exception is thrown
720809500fcSDimitry Andric   // later in the constructor.
721809500fcSDimitry Andric   QualType::DestructionKind dtorKind = FieldType.isDestructedType();
722809500fcSDimitry Andric   if (needsEHCleanup(dtorKind))
723ac9a064cSDimitry Andric     pushEHDestroy(dtorKind, LHS.getAddress(), FieldType);
724809500fcSDimitry Andric }
725809500fcSDimitry Andric 
72679ade4e0SRoman Divacky /// Checks whether the given constructor is a valid subject for the
72779ade4e0SRoman Divacky /// complete-to-base constructor delegation optimization, i.e.
72879ade4e0SRoman Divacky /// emitting the complete constructor as a simple call to the base
72979ade4e0SRoman Divacky /// constructor.
IsConstructorDelegationValid(const CXXConstructorDecl * Ctor)7307442d6faSDimitry Andric bool CodeGenFunction::IsConstructorDelegationValid(
7317442d6faSDimitry Andric     const CXXConstructorDecl *Ctor) {
73279ade4e0SRoman Divacky 
73379ade4e0SRoman Divacky   // Currently we disable the optimization for classes with virtual
73479ade4e0SRoman Divacky   // bases because (1) the addresses of parameter variables need to be
73579ade4e0SRoman Divacky   // consistent across all initializers but (2) the delegate function
73679ade4e0SRoman Divacky   // call necessarily creates a second copy of the parameter variable.
73779ade4e0SRoman Divacky   //
73879ade4e0SRoman Divacky   // The limiting example (purely theoretical AFAIK):
73979ade4e0SRoman Divacky   //   struct A { A(int &c) { c++; } };
74079ade4e0SRoman Divacky   //   struct B : virtual A {
74179ade4e0SRoman Divacky   //     B(int count) : A(count) { printf("%d\n", count); }
74279ade4e0SRoman Divacky   //   };
74379ade4e0SRoman Divacky   // ...although even this example could in principle be emitted as a
74479ade4e0SRoman Divacky   // delegation since the address of the parameter doesn't escape.
74579ade4e0SRoman Divacky   if (Ctor->getParent()->getNumVBases()) {
74679ade4e0SRoman Divacky     // TODO: white-list trivial vbase initializers.  This case wouldn't
74779ade4e0SRoman Divacky     // be subject to the restrictions below.
74879ade4e0SRoman Divacky 
74979ade4e0SRoman Divacky     // TODO: white-list cases where:
75079ade4e0SRoman Divacky     //  - there are no non-reference parameters to the constructor
75179ade4e0SRoman Divacky     //  - the initializers don't access any non-reference parameters
75279ade4e0SRoman Divacky     //  - the initializers don't take the address of non-reference
75379ade4e0SRoman Divacky     //    parameters
75479ade4e0SRoman Divacky     //  - etc.
75579ade4e0SRoman Divacky     // If we ever add any of the above cases, remember that:
756cfca06d7SDimitry Andric     //  - function-try-blocks will always exclude this optimization
75779ade4e0SRoman Divacky     //  - we need to perform the constructor prologue and cleanup in
75879ade4e0SRoman Divacky     //    EmitConstructorBody.
75979ade4e0SRoman Divacky 
76079ade4e0SRoman Divacky     return false;
76179ade4e0SRoman Divacky   }
76279ade4e0SRoman Divacky 
76379ade4e0SRoman Divacky   // We also disable the optimization for variadic functions because
76479ade4e0SRoman Divacky   // it's impossible to "re-pass" varargs.
765519fc96cSDimitry Andric   if (Ctor->getType()->castAs<FunctionProtoType>()->isVariadic())
76679ade4e0SRoman Divacky     return false;
76779ade4e0SRoman Divacky 
76801af97d3SDimitry Andric   // FIXME: Decide if we can do a delegation of a delegating constructor.
76901af97d3SDimitry Andric   if (Ctor->isDelegatingConstructor())
77001af97d3SDimitry Andric     return false;
77101af97d3SDimitry Andric 
77279ade4e0SRoman Divacky   return true;
77379ade4e0SRoman Divacky }
77479ade4e0SRoman Divacky 
77506d4ba38SDimitry Andric // Emit code in ctor (Prologue==true) or dtor (Prologue==false)
77606d4ba38SDimitry Andric // to poison the extra field paddings inserted under
77706d4ba38SDimitry Andric // -fsanitize-address-field-padding=1|2.
EmitAsanPrologueOrEpilogue(bool Prologue)77806d4ba38SDimitry Andric void CodeGenFunction::EmitAsanPrologueOrEpilogue(bool Prologue) {
77906d4ba38SDimitry Andric   ASTContext &Context = getContext();
78006d4ba38SDimitry Andric   const CXXRecordDecl *ClassDecl =
78106d4ba38SDimitry Andric       Prologue ? cast<CXXConstructorDecl>(CurGD.getDecl())->getParent()
78206d4ba38SDimitry Andric                : cast<CXXDestructorDecl>(CurGD.getDecl())->getParent();
78306d4ba38SDimitry Andric   if (!ClassDecl->mayInsertExtraPadding()) return;
78406d4ba38SDimitry Andric 
78506d4ba38SDimitry Andric   struct SizeAndOffset {
78606d4ba38SDimitry Andric     uint64_t Size;
78706d4ba38SDimitry Andric     uint64_t Offset;
78806d4ba38SDimitry Andric   };
78906d4ba38SDimitry Andric 
79006d4ba38SDimitry Andric   unsigned PtrSize = CGM.getDataLayout().getPointerSizeInBits();
79106d4ba38SDimitry Andric   const ASTRecordLayout &Info = Context.getASTRecordLayout(ClassDecl);
79206d4ba38SDimitry Andric 
79306d4ba38SDimitry Andric   // Populate sizes and offsets of fields.
79406d4ba38SDimitry Andric   SmallVector<SizeAndOffset, 16> SSV(Info.getFieldCount());
79506d4ba38SDimitry Andric   for (unsigned i = 0, e = Info.getFieldCount(); i != e; ++i)
79606d4ba38SDimitry Andric     SSV[i].Offset =
79706d4ba38SDimitry Andric         Context.toCharUnitsFromBits(Info.getFieldOffset(i)).getQuantity();
79806d4ba38SDimitry Andric 
79906d4ba38SDimitry Andric   size_t NumFields = 0;
80006d4ba38SDimitry Andric   for (const auto *Field : ClassDecl->fields()) {
80106d4ba38SDimitry Andric     const FieldDecl *D = Field;
802b60736ecSDimitry Andric     auto FieldInfo = Context.getTypeInfoInChars(D->getType());
803b60736ecSDimitry Andric     CharUnits FieldSize = FieldInfo.Width;
80406d4ba38SDimitry Andric     assert(NumFields < SSV.size());
80506d4ba38SDimitry Andric     SSV[NumFields].Size = D->isBitField() ? 0 : FieldSize.getQuantity();
80606d4ba38SDimitry Andric     NumFields++;
80706d4ba38SDimitry Andric   }
80806d4ba38SDimitry Andric   assert(NumFields == SSV.size());
80906d4ba38SDimitry Andric   if (SSV.size() <= 1) return;
81006d4ba38SDimitry Andric 
81106d4ba38SDimitry Andric   // We will insert calls to __asan_* run-time functions.
81206d4ba38SDimitry Andric   // LLVM AddressSanitizer pass may decide to inline them later.
81306d4ba38SDimitry Andric   llvm::Type *Args[2] = {IntPtrTy, IntPtrTy};
81406d4ba38SDimitry Andric   llvm::FunctionType *FTy =
81506d4ba38SDimitry Andric       llvm::FunctionType::get(CGM.VoidTy, Args, false);
81622989816SDimitry Andric   llvm::FunctionCallee F = CGM.CreateRuntimeFunction(
81706d4ba38SDimitry Andric       FTy, Prologue ? "__asan_poison_intra_object_redzone"
81806d4ba38SDimitry Andric                     : "__asan_unpoison_intra_object_redzone");
81906d4ba38SDimitry Andric 
82006d4ba38SDimitry Andric   llvm::Value *ThisPtr = LoadCXXThis();
82106d4ba38SDimitry Andric   ThisPtr = Builder.CreatePtrToInt(ThisPtr, IntPtrTy);
82206d4ba38SDimitry Andric   uint64_t TypeSize = Info.getNonVirtualSize().getQuantity();
82306d4ba38SDimitry Andric   // For each field check if it has sufficient padding,
82406d4ba38SDimitry Andric   // if so (un)poison it with a call.
82506d4ba38SDimitry Andric   for (size_t i = 0; i < SSV.size(); i++) {
82606d4ba38SDimitry Andric     uint64_t AsanAlignment = 8;
82706d4ba38SDimitry Andric     uint64_t NextField = i == SSV.size() - 1 ? TypeSize : SSV[i + 1].Offset;
82806d4ba38SDimitry Andric     uint64_t PoisonSize = NextField - SSV[i].Offset - SSV[i].Size;
82906d4ba38SDimitry Andric     uint64_t EndOffset = SSV[i].Offset + SSV[i].Size;
83006d4ba38SDimitry Andric     if (PoisonSize < AsanAlignment || !SSV[i].Size ||
83106d4ba38SDimitry Andric         (NextField % AsanAlignment) != 0)
83206d4ba38SDimitry Andric       continue;
8335e20cdd8SDimitry Andric     Builder.CreateCall(
8345e20cdd8SDimitry Andric         F, {Builder.CreateAdd(ThisPtr, Builder.getIntN(PtrSize, EndOffset)),
8355e20cdd8SDimitry Andric             Builder.getIntN(PtrSize, PoisonSize)});
83606d4ba38SDimitry Andric   }
83706d4ba38SDimitry Andric }
83806d4ba38SDimitry Andric 
83979ade4e0SRoman Divacky /// EmitConstructorBody - Emits the body of the current constructor.
EmitConstructorBody(FunctionArgList & Args)84079ade4e0SRoman Divacky void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) {
84106d4ba38SDimitry Andric   EmitAsanPrologueOrEpilogue(true);
84279ade4e0SRoman Divacky   const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl());
84379ade4e0SRoman Divacky   CXXCtorType CtorType = CurGD.getCtorType();
84479ade4e0SRoman Divacky 
8459f4dbff6SDimitry Andric   assert((CGM.getTarget().getCXXABI().hasConstructorVariants() ||
8469f4dbff6SDimitry Andric           CtorType == Ctor_Complete) &&
8479f4dbff6SDimitry Andric          "can only generate complete ctor for this ABI");
8489f4dbff6SDimitry Andric 
84979ade4e0SRoman Divacky   // Before we go any further, try the complete->base constructor
85079ade4e0SRoman Divacky   // delegation optimization.
85156d91b49SDimitry Andric   if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor) &&
8526a037251SDimitry Andric       CGM.getTarget().getCXXABI().hasConstructorVariants()) {
853676fbe81SDimitry Andric     EmitDelegateCXXConstructorCall(Ctor, Ctor_Base, Args, Ctor->getEndLoc());
85479ade4e0SRoman Divacky     return;
85579ade4e0SRoman Divacky   }
85679ade4e0SRoman Divacky 
85745b53394SDimitry Andric   const FunctionDecl *Definition = nullptr;
85806d4ba38SDimitry Andric   Stmt *Body = Ctor->getBody(Definition);
85906d4ba38SDimitry Andric   assert(Definition == Ctor && "emitting wrong constructor body");
86079ade4e0SRoman Divacky 
86179ade4e0SRoman Divacky   // Enter the function-try-block before the constructor prologue if
86279ade4e0SRoman Divacky   // applicable.
863ac9a064cSDimitry Andric   bool IsTryBody = isa_and_nonnull<CXXTryStmt>(Body);
86479ade4e0SRoman Divacky   if (IsTryBody)
8654ba67500SRoman Divacky     EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true);
86679ade4e0SRoman Divacky 
8675e20cdd8SDimitry Andric   incrementProfileCounter(Body);
868aca2e42cSDimitry Andric   maybeCreateMCDCCondBitmap();
8699f4dbff6SDimitry Andric 
870bfef3995SDimitry Andric   RunCleanupsScope RunCleanups(*this);
87179ade4e0SRoman Divacky 
872dbe13110SDimitry Andric   // TODO: in restricted cases, we can emit the vbase initializers of
873dbe13110SDimitry Andric   // a complete ctor and then delegate to the base ctor.
874dbe13110SDimitry Andric 
87579ade4e0SRoman Divacky   // Emit the constructor prologue, i.e. the base and member
87679ade4e0SRoman Divacky   // initializers.
877d7279c4cSRoman Divacky   EmitCtorPrologue(Ctor, CtorType, Args);
87879ade4e0SRoman Divacky 
87979ade4e0SRoman Divacky   // Emit the body of the statement.
88079ade4e0SRoman Divacky   if (IsTryBody)
88179ade4e0SRoman Divacky     EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
88279ade4e0SRoman Divacky   else if (Body)
88379ade4e0SRoman Divacky     EmitStmt(Body);
88479ade4e0SRoman Divacky 
88579ade4e0SRoman Divacky   // Emit any cleanup blocks associated with the member or base
88679ade4e0SRoman Divacky   // initializers, which includes (along the exceptional path) the
88779ade4e0SRoman Divacky   // destructors for those members and bases that were fully
88879ade4e0SRoman Divacky   // constructed.
889bfef3995SDimitry Andric   RunCleanups.ForceCleanup();
89079ade4e0SRoman Divacky 
89179ade4e0SRoman Divacky   if (IsTryBody)
8924ba67500SRoman Divacky     ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);
89379ade4e0SRoman Divacky }
89479ade4e0SRoman Divacky 
895809500fcSDimitry Andric namespace {
896bfef3995SDimitry Andric   /// RAII object to indicate that codegen is copying the value representation
897bfef3995SDimitry Andric   /// instead of the object representation. Useful when copying a struct or
898bfef3995SDimitry Andric   /// class which has uninitialized members and we're only performing
899bfef3995SDimitry Andric   /// lvalue-to-rvalue conversion on the object but not its members.
900bfef3995SDimitry Andric   class CopyingValueRepresentation {
901bfef3995SDimitry Andric   public:
CopyingValueRepresentation(CodeGenFunction & CGF)902bfef3995SDimitry Andric     explicit CopyingValueRepresentation(CodeGenFunction &CGF)
90306d4ba38SDimitry Andric         : CGF(CGF), OldSanOpts(CGF.SanOpts) {
90406d4ba38SDimitry Andric       CGF.SanOpts.set(SanitizerKind::Bool, false);
90506d4ba38SDimitry Andric       CGF.SanOpts.set(SanitizerKind::Enum, false);
906bfef3995SDimitry Andric     }
~CopyingValueRepresentation()907bfef3995SDimitry Andric     ~CopyingValueRepresentation() {
908bfef3995SDimitry Andric       CGF.SanOpts = OldSanOpts;
909bfef3995SDimitry Andric     }
910bfef3995SDimitry Andric   private:
911bfef3995SDimitry Andric     CodeGenFunction &CGF;
91206d4ba38SDimitry Andric     SanitizerSet OldSanOpts;
913bfef3995SDimitry Andric   };
9142b6b257fSDimitry Andric } // end anonymous namespace
915bfef3995SDimitry Andric 
916bfef3995SDimitry Andric namespace {
917809500fcSDimitry Andric   class FieldMemcpyizer {
918809500fcSDimitry Andric   public:
FieldMemcpyizer(CodeGenFunction & CGF,const CXXRecordDecl * ClassDecl,const VarDecl * SrcRec)919809500fcSDimitry Andric     FieldMemcpyizer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl,
920809500fcSDimitry Andric                     const VarDecl *SrcRec)
921809500fcSDimitry Andric       : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec),
922809500fcSDimitry Andric         RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)),
9239f4dbff6SDimitry Andric         FirstField(nullptr), LastField(nullptr), FirstFieldOffset(0),
9249f4dbff6SDimitry Andric         LastFieldOffset(0), LastAddedFieldIndex(0) {}
925809500fcSDimitry Andric 
isMemcpyableField(FieldDecl * F) const92606d4ba38SDimitry Andric     bool isMemcpyableField(FieldDecl *F) const {
92706d4ba38SDimitry Andric       // Never memcpy fields when we are adding poisoned paddings.
92806d4ba38SDimitry Andric       if (CGF.getContext().getLangOpts().SanitizeAddressFieldPadding)
92906d4ba38SDimitry Andric         return false;
930809500fcSDimitry Andric       Qualifiers Qual = F->getType().getQualifiers();
931809500fcSDimitry Andric       if (Qual.hasVolatile() || Qual.hasObjCLifetime())
932809500fcSDimitry Andric         return false;
933809500fcSDimitry Andric       return true;
934809500fcSDimitry Andric     }
935809500fcSDimitry Andric 
addMemcpyableField(FieldDecl * F)936809500fcSDimitry Andric     void addMemcpyableField(FieldDecl *F) {
937ac9a064cSDimitry Andric       if (isEmptyFieldForLayout(CGF.getContext(), F))
938706b4fc4SDimitry Andric         return;
9399f4dbff6SDimitry Andric       if (!FirstField)
940809500fcSDimitry Andric         addInitialField(F);
941809500fcSDimitry Andric       else
942809500fcSDimitry Andric         addNextField(F);
943809500fcSDimitry Andric     }
944809500fcSDimitry Andric 
getMemcpySize(uint64_t FirstByteOffset) const94506d4ba38SDimitry Andric     CharUnits getMemcpySize(uint64_t FirstByteOffset) const {
94648675466SDimitry Andric       ASTContext &Ctx = CGF.getContext();
947809500fcSDimitry Andric       unsigned LastFieldSize =
94848675466SDimitry Andric           LastField->isBitField()
94948675466SDimitry Andric               ? LastField->getBitWidthValue(Ctx)
95048675466SDimitry Andric               : Ctx.toBits(
951b60736ecSDimitry Andric                     Ctx.getTypeInfoDataSizeInChars(LastField->getType()).Width);
95248675466SDimitry Andric       uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize -
95348675466SDimitry Andric                                 FirstByteOffset + Ctx.getCharWidth() - 1;
95448675466SDimitry Andric       CharUnits MemcpySize = Ctx.toCharUnitsFromBits(MemcpySizeBits);
955809500fcSDimitry Andric       return MemcpySize;
956809500fcSDimitry Andric     }
957809500fcSDimitry Andric 
emitMemcpy()958809500fcSDimitry Andric     void emitMemcpy() {
959809500fcSDimitry Andric       // Give the subclass a chance to bail out if it feels the memcpy isn't
960809500fcSDimitry Andric       // worth it (e.g. Hasn't aggregated enough data).
9619f4dbff6SDimitry Andric       if (!FirstField) {
962809500fcSDimitry Andric         return;
963809500fcSDimitry Andric       }
964809500fcSDimitry Andric 
96506d4ba38SDimitry Andric       uint64_t FirstByteOffset;
966809500fcSDimitry Andric       if (FirstField->isBitField()) {
967809500fcSDimitry Andric         const CGRecordLayout &RL =
968809500fcSDimitry Andric           CGF.getTypes().getCGRecordLayout(FirstField->getParent());
969809500fcSDimitry Andric         const CGBitFieldInfo &BFInfo = RL.getBitFieldInfo(FirstField);
97006d4ba38SDimitry Andric         // FirstFieldOffset is not appropriate for bitfields,
97151ece4aaSDimitry Andric         // we need to use the storage offset instead.
97251ece4aaSDimitry Andric         FirstByteOffset = CGF.getContext().toBits(BFInfo.StorageOffset);
973809500fcSDimitry Andric       } else {
97406d4ba38SDimitry Andric         FirstByteOffset = FirstFieldOffset;
975809500fcSDimitry Andric       }
976809500fcSDimitry Andric 
97706d4ba38SDimitry Andric       CharUnits MemcpySize = getMemcpySize(FirstByteOffset);
978809500fcSDimitry Andric       QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
97945b53394SDimitry Andric       Address ThisPtr = CGF.LoadCXXThisAddress();
98045b53394SDimitry Andric       LValue DestLV = CGF.MakeAddrLValue(ThisPtr, RecordTy);
981809500fcSDimitry Andric       LValue Dest = CGF.EmitLValueForFieldInitialization(DestLV, FirstField);
982809500fcSDimitry Andric       llvm::Value *SrcPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(SrcRec));
983809500fcSDimitry Andric       LValue SrcLV = CGF.MakeNaturalAlignAddrLValue(SrcPtr, RecordTy);
984809500fcSDimitry Andric       LValue Src = CGF.EmitLValueForFieldInitialization(SrcLV, FirstField);
985809500fcSDimitry Andric 
986706b4fc4SDimitry Andric       emitMemcpyIR(
987ac9a064cSDimitry Andric           Dest.isBitField() ? Dest.getBitFieldAddress() : Dest.getAddress(),
988ac9a064cSDimitry Andric           Src.isBitField() ? Src.getBitFieldAddress() : Src.getAddress(),
98945b53394SDimitry Andric           MemcpySize);
990809500fcSDimitry Andric       reset();
991809500fcSDimitry Andric     }
992809500fcSDimitry Andric 
reset()993809500fcSDimitry Andric     void reset() {
9949f4dbff6SDimitry Andric       FirstField = nullptr;
995809500fcSDimitry Andric     }
996809500fcSDimitry Andric 
997809500fcSDimitry Andric   protected:
998809500fcSDimitry Andric     CodeGenFunction &CGF;
999809500fcSDimitry Andric     const CXXRecordDecl *ClassDecl;
1000809500fcSDimitry Andric 
1001809500fcSDimitry Andric   private:
emitMemcpyIR(Address DestPtr,Address SrcPtr,CharUnits Size)100245b53394SDimitry Andric     void emitMemcpyIR(Address DestPtr, Address SrcPtr, CharUnits Size) {
10037fa27ce4SDimitry Andric       DestPtr = DestPtr.withElementType(CGF.Int8Ty);
10047fa27ce4SDimitry Andric       SrcPtr = SrcPtr.withElementType(CGF.Int8Ty);
100545b53394SDimitry Andric       CGF.Builder.CreateMemCpy(DestPtr, SrcPtr, Size.getQuantity());
1006809500fcSDimitry Andric     }
1007809500fcSDimitry Andric 
addInitialField(FieldDecl * F)1008809500fcSDimitry Andric     void addInitialField(FieldDecl *F) {
1009809500fcSDimitry Andric       FirstField = F;
1010809500fcSDimitry Andric       LastField = F;
1011809500fcSDimitry Andric       FirstFieldOffset = RecLayout.getFieldOffset(F->getFieldIndex());
1012809500fcSDimitry Andric       LastFieldOffset = FirstFieldOffset;
1013809500fcSDimitry Andric       LastAddedFieldIndex = F->getFieldIndex();
1014809500fcSDimitry Andric     }
1015809500fcSDimitry Andric 
addNextField(FieldDecl * F)1016809500fcSDimitry Andric     void addNextField(FieldDecl *F) {
1017bfef3995SDimitry Andric       // For the most part, the following invariant will hold:
1018bfef3995SDimitry Andric       //   F->getFieldIndex() == LastAddedFieldIndex + 1
1019bfef3995SDimitry Andric       // The one exception is that Sema won't add a copy-initializer for an
1020bfef3995SDimitry Andric       // unnamed bitfield, which will show up here as a gap in the sequence.
1021bfef3995SDimitry Andric       assert(F->getFieldIndex() >= LastAddedFieldIndex + 1 &&
1022bfef3995SDimitry Andric              "Cannot aggregate fields out of order.");
1023809500fcSDimitry Andric       LastAddedFieldIndex = F->getFieldIndex();
1024809500fcSDimitry Andric 
1025809500fcSDimitry Andric       // The 'first' and 'last' fields are chosen by offset, rather than field
1026809500fcSDimitry Andric       // index. This allows the code to support bitfields, as well as regular
1027809500fcSDimitry Andric       // fields.
1028809500fcSDimitry Andric       uint64_t FOffset = RecLayout.getFieldOffset(F->getFieldIndex());
1029809500fcSDimitry Andric       if (FOffset < FirstFieldOffset) {
1030809500fcSDimitry Andric         FirstField = F;
1031809500fcSDimitry Andric         FirstFieldOffset = FOffset;
103222989816SDimitry Andric       } else if (FOffset >= LastFieldOffset) {
1033809500fcSDimitry Andric         LastField = F;
1034809500fcSDimitry Andric         LastFieldOffset = FOffset;
1035809500fcSDimitry Andric       }
1036809500fcSDimitry Andric     }
1037809500fcSDimitry Andric 
1038809500fcSDimitry Andric     const VarDecl *SrcRec;
1039809500fcSDimitry Andric     const ASTRecordLayout &RecLayout;
1040809500fcSDimitry Andric     FieldDecl *FirstField;
1041809500fcSDimitry Andric     FieldDecl *LastField;
1042809500fcSDimitry Andric     uint64_t FirstFieldOffset, LastFieldOffset;
1043809500fcSDimitry Andric     unsigned LastAddedFieldIndex;
1044809500fcSDimitry Andric   };
1045809500fcSDimitry Andric 
1046809500fcSDimitry Andric   class ConstructorMemcpyizer : public FieldMemcpyizer {
1047809500fcSDimitry Andric   private:
1048809500fcSDimitry Andric     /// Get source argument for copy constructor. Returns null if not a copy
1049809500fcSDimitry Andric     /// constructor.
getTrivialCopySource(CodeGenFunction & CGF,const CXXConstructorDecl * CD,FunctionArgList & Args)105006d4ba38SDimitry Andric     static const VarDecl *getTrivialCopySource(CodeGenFunction &CGF,
105106d4ba38SDimitry Andric                                                const CXXConstructorDecl *CD,
1052809500fcSDimitry Andric                                                FunctionArgList &Args) {
1053bfef3995SDimitry Andric       if (CD->isCopyOrMoveConstructor() && CD->isDefaulted())
105406d4ba38SDimitry Andric         return Args[CGF.CGM.getCXXABI().getSrcArgforCopyCtor(CD, Args)];
10559f4dbff6SDimitry Andric       return nullptr;
1056809500fcSDimitry Andric     }
1057809500fcSDimitry Andric 
1058809500fcSDimitry Andric     // Returns true if a CXXCtorInitializer represents a member initialization
1059809500fcSDimitry Andric     // that can be rolled into a memcpy.
isMemberInitMemcpyable(CXXCtorInitializer * MemberInit) const1060809500fcSDimitry Andric     bool isMemberInitMemcpyable(CXXCtorInitializer *MemberInit) const {
1061809500fcSDimitry Andric       if (!MemcpyableCtor)
1062809500fcSDimitry Andric         return false;
1063809500fcSDimitry Andric       FieldDecl *Field = MemberInit->getMember();
10649f4dbff6SDimitry Andric       assert(Field && "No field for member init.");
1065809500fcSDimitry Andric       QualType FieldType = Field->getType();
1066809500fcSDimitry Andric       CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit());
1067809500fcSDimitry Andric 
10685e20cdd8SDimitry Andric       // Bail out on non-memcpyable, not-trivially-copyable members.
10695e20cdd8SDimitry Andric       if (!(CE && isMemcpyEquivalentSpecialMember(CE->getConstructor())) &&
1070809500fcSDimitry Andric           !(FieldType.isTriviallyCopyableType(CGF.getContext()) ||
1071809500fcSDimitry Andric             FieldType->isReferenceType()))
1072809500fcSDimitry Andric         return false;
1073809500fcSDimitry Andric 
1074809500fcSDimitry Andric       // Bail out on volatile fields.
1075809500fcSDimitry Andric       if (!isMemcpyableField(Field))
1076809500fcSDimitry Andric         return false;
1077809500fcSDimitry Andric 
1078809500fcSDimitry Andric       // Otherwise we're good.
1079809500fcSDimitry Andric       return true;
1080809500fcSDimitry Andric     }
1081809500fcSDimitry Andric 
1082809500fcSDimitry Andric   public:
ConstructorMemcpyizer(CodeGenFunction & CGF,const CXXConstructorDecl * CD,FunctionArgList & Args)1083809500fcSDimitry Andric     ConstructorMemcpyizer(CodeGenFunction &CGF, const CXXConstructorDecl *CD,
1084809500fcSDimitry Andric                           FunctionArgList &Args)
108506d4ba38SDimitry Andric       : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CGF, CD, Args)),
1086809500fcSDimitry Andric         ConstructorDecl(CD),
1087bfef3995SDimitry Andric         MemcpyableCtor(CD->isDefaulted() &&
1088809500fcSDimitry Andric                        CD->isCopyOrMoveConstructor() &&
1089809500fcSDimitry Andric                        CGF.getLangOpts().getGC() == LangOptions::NonGC),
1090809500fcSDimitry Andric         Args(Args) { }
1091809500fcSDimitry Andric 
addMemberInitializer(CXXCtorInitializer * MemberInit)1092809500fcSDimitry Andric     void addMemberInitializer(CXXCtorInitializer *MemberInit) {
1093809500fcSDimitry Andric       if (isMemberInitMemcpyable(MemberInit)) {
1094809500fcSDimitry Andric         AggregatedInits.push_back(MemberInit);
1095809500fcSDimitry Andric         addMemcpyableField(MemberInit->getMember());
1096809500fcSDimitry Andric       } else {
1097809500fcSDimitry Andric         emitAggregatedInits();
1098809500fcSDimitry Andric         EmitMemberInitializer(CGF, ConstructorDecl->getParent(), MemberInit,
1099809500fcSDimitry Andric                               ConstructorDecl, Args);
1100809500fcSDimitry Andric       }
1101809500fcSDimitry Andric     }
1102809500fcSDimitry Andric 
emitAggregatedInits()1103809500fcSDimitry Andric     void emitAggregatedInits() {
1104809500fcSDimitry Andric       if (AggregatedInits.size() <= 1) {
1105809500fcSDimitry Andric         // This memcpy is too small to be worthwhile. Fall back on default
1106809500fcSDimitry Andric         // codegen.
1107bfef3995SDimitry Andric         if (!AggregatedInits.empty()) {
1108bfef3995SDimitry Andric           CopyingValueRepresentation CVR(CGF);
1109809500fcSDimitry Andric           EmitMemberInitializer(CGF, ConstructorDecl->getParent(),
1110bfef3995SDimitry Andric                                 AggregatedInits[0], ConstructorDecl, Args);
111151ece4aaSDimitry Andric           AggregatedInits.clear();
1112809500fcSDimitry Andric         }
1113809500fcSDimitry Andric         reset();
1114809500fcSDimitry Andric         return;
1115809500fcSDimitry Andric       }
1116809500fcSDimitry Andric 
1117809500fcSDimitry Andric       pushEHDestructors();
1118809500fcSDimitry Andric       emitMemcpy();
1119809500fcSDimitry Andric       AggregatedInits.clear();
1120809500fcSDimitry Andric     }
1121809500fcSDimitry Andric 
pushEHDestructors()1122809500fcSDimitry Andric     void pushEHDestructors() {
112345b53394SDimitry Andric       Address ThisPtr = CGF.LoadCXXThisAddress();
1124809500fcSDimitry Andric       QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
112545b53394SDimitry Andric       LValue LHS = CGF.MakeAddrLValue(ThisPtr, RecordTy);
1126809500fcSDimitry Andric 
1127809500fcSDimitry Andric       for (unsigned i = 0; i < AggregatedInits.size(); ++i) {
112851ece4aaSDimitry Andric         CXXCtorInitializer *MemberInit = AggregatedInits[i];
112951ece4aaSDimitry Andric         QualType FieldType = MemberInit->getAnyMember()->getType();
1130809500fcSDimitry Andric         QualType::DestructionKind dtorKind = FieldType.isDestructedType();
113151ece4aaSDimitry Andric         if (!CGF.needsEHCleanup(dtorKind))
113251ece4aaSDimitry Andric           continue;
113351ece4aaSDimitry Andric         LValue FieldLHS = LHS;
113451ece4aaSDimitry Andric         EmitLValueForAnyFieldInitialization(CGF, MemberInit, FieldLHS);
1135ac9a064cSDimitry Andric         CGF.pushEHDestroy(dtorKind, FieldLHS.getAddress(), FieldType);
1136809500fcSDimitry Andric       }
1137809500fcSDimitry Andric     }
1138809500fcSDimitry Andric 
finish()1139809500fcSDimitry Andric     void finish() {
1140809500fcSDimitry Andric       emitAggregatedInits();
1141809500fcSDimitry Andric     }
1142809500fcSDimitry Andric 
1143809500fcSDimitry Andric   private:
1144809500fcSDimitry Andric     const CXXConstructorDecl *ConstructorDecl;
1145809500fcSDimitry Andric     bool MemcpyableCtor;
1146809500fcSDimitry Andric     FunctionArgList &Args;
1147809500fcSDimitry Andric     SmallVector<CXXCtorInitializer*, 16> AggregatedInits;
1148809500fcSDimitry Andric   };
1149809500fcSDimitry Andric 
1150809500fcSDimitry Andric   class AssignmentMemcpyizer : public FieldMemcpyizer {
1151809500fcSDimitry Andric   private:
1152809500fcSDimitry Andric     // Returns the memcpyable field copied by the given statement, if one
1153bfef3995SDimitry Andric     // exists. Otherwise returns null.
getMemcpyableField(Stmt * S)1154809500fcSDimitry Andric     FieldDecl *getMemcpyableField(Stmt *S) {
1155809500fcSDimitry Andric       if (!AssignmentsMemcpyable)
11569f4dbff6SDimitry Andric         return nullptr;
1157809500fcSDimitry Andric       if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) {
1158809500fcSDimitry Andric         // Recognise trivial assignments.
1159809500fcSDimitry Andric         if (BO->getOpcode() != BO_Assign)
11609f4dbff6SDimitry Andric           return nullptr;
1161809500fcSDimitry Andric         MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS());
1162809500fcSDimitry Andric         if (!ME)
11639f4dbff6SDimitry Andric           return nullptr;
1164809500fcSDimitry Andric         FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl());
1165809500fcSDimitry Andric         if (!Field || !isMemcpyableField(Field))
11669f4dbff6SDimitry Andric           return nullptr;
1167809500fcSDimitry Andric         Stmt *RHS = BO->getRHS();
1168809500fcSDimitry Andric         if (ImplicitCastExpr *EC = dyn_cast<ImplicitCastExpr>(RHS))
1169809500fcSDimitry Andric           RHS = EC->getSubExpr();
1170809500fcSDimitry Andric         if (!RHS)
11719f4dbff6SDimitry Andric           return nullptr;
11727442d6faSDimitry Andric         if (MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) {
11737442d6faSDimitry Andric           if (ME2->getMemberDecl() == Field)
1174809500fcSDimitry Andric             return Field;
11757442d6faSDimitry Andric         }
11767442d6faSDimitry Andric         return nullptr;
1177809500fcSDimitry Andric       } else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) {
1178809500fcSDimitry Andric         CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl());
11795e20cdd8SDimitry Andric         if (!(MD && isMemcpyEquivalentSpecialMember(MD)))
11809f4dbff6SDimitry Andric           return nullptr;
1181809500fcSDimitry Andric         MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument());
1182809500fcSDimitry Andric         if (!IOA)
11839f4dbff6SDimitry Andric           return nullptr;
1184809500fcSDimitry Andric         FieldDecl *Field = dyn_cast<FieldDecl>(IOA->getMemberDecl());
1185809500fcSDimitry Andric         if (!Field || !isMemcpyableField(Field))
11869f4dbff6SDimitry Andric           return nullptr;
1187809500fcSDimitry Andric         MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0));
1188809500fcSDimitry Andric         if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->getMemberDecl()))
11899f4dbff6SDimitry Andric           return nullptr;
1190809500fcSDimitry Andric         return Field;
1191809500fcSDimitry Andric       } else if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
1192809500fcSDimitry Andric         FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
1193809500fcSDimitry Andric         if (!FD || FD->getBuiltinID() != Builtin::BI__builtin_memcpy)
11949f4dbff6SDimitry Andric           return nullptr;
1195809500fcSDimitry Andric         Expr *DstPtr = CE->getArg(0);
1196809500fcSDimitry Andric         if (ImplicitCastExpr *DC = dyn_cast<ImplicitCastExpr>(DstPtr))
1197809500fcSDimitry Andric           DstPtr = DC->getSubExpr();
1198809500fcSDimitry Andric         UnaryOperator *DUO = dyn_cast<UnaryOperator>(DstPtr);
1199809500fcSDimitry Andric         if (!DUO || DUO->getOpcode() != UO_AddrOf)
12009f4dbff6SDimitry Andric           return nullptr;
1201809500fcSDimitry Andric         MemberExpr *ME = dyn_cast<MemberExpr>(DUO->getSubExpr());
1202809500fcSDimitry Andric         if (!ME)
12039f4dbff6SDimitry Andric           return nullptr;
1204809500fcSDimitry Andric         FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl());
1205809500fcSDimitry Andric         if (!Field || !isMemcpyableField(Field))
12069f4dbff6SDimitry Andric           return nullptr;
1207809500fcSDimitry Andric         Expr *SrcPtr = CE->getArg(1);
1208809500fcSDimitry Andric         if (ImplicitCastExpr *SC = dyn_cast<ImplicitCastExpr>(SrcPtr))
1209809500fcSDimitry Andric           SrcPtr = SC->getSubExpr();
1210809500fcSDimitry Andric         UnaryOperator *SUO = dyn_cast<UnaryOperator>(SrcPtr);
1211809500fcSDimitry Andric         if (!SUO || SUO->getOpcode() != UO_AddrOf)
12129f4dbff6SDimitry Andric           return nullptr;
1213809500fcSDimitry Andric         MemberExpr *ME2 = dyn_cast<MemberExpr>(SUO->getSubExpr());
1214809500fcSDimitry Andric         if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->getMemberDecl()))
12159f4dbff6SDimitry Andric           return nullptr;
1216809500fcSDimitry Andric         return Field;
1217809500fcSDimitry Andric       }
1218809500fcSDimitry Andric 
12199f4dbff6SDimitry Andric       return nullptr;
1220809500fcSDimitry Andric     }
1221809500fcSDimitry Andric 
1222809500fcSDimitry Andric     bool AssignmentsMemcpyable;
1223809500fcSDimitry Andric     SmallVector<Stmt*, 16> AggregatedStmts;
1224809500fcSDimitry Andric 
1225809500fcSDimitry Andric   public:
AssignmentMemcpyizer(CodeGenFunction & CGF,const CXXMethodDecl * AD,FunctionArgList & Args)1226809500fcSDimitry Andric     AssignmentMemcpyizer(CodeGenFunction &CGF, const CXXMethodDecl *AD,
1227809500fcSDimitry Andric                          FunctionArgList &Args)
1228809500fcSDimitry Andric       : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]),
1229809500fcSDimitry Andric         AssignmentsMemcpyable(CGF.getLangOpts().getGC() == LangOptions::NonGC) {
1230809500fcSDimitry Andric       assert(Args.size() == 2);
1231809500fcSDimitry Andric     }
1232809500fcSDimitry Andric 
emitAssignment(Stmt * S)1233809500fcSDimitry Andric     void emitAssignment(Stmt *S) {
1234809500fcSDimitry Andric       FieldDecl *F = getMemcpyableField(S);
1235809500fcSDimitry Andric       if (F) {
1236809500fcSDimitry Andric         addMemcpyableField(F);
1237809500fcSDimitry Andric         AggregatedStmts.push_back(S);
1238809500fcSDimitry Andric       } else {
1239809500fcSDimitry Andric         emitAggregatedStmts();
1240809500fcSDimitry Andric         CGF.EmitStmt(S);
1241809500fcSDimitry Andric       }
1242809500fcSDimitry Andric     }
1243809500fcSDimitry Andric 
emitAggregatedStmts()1244809500fcSDimitry Andric     void emitAggregatedStmts() {
1245809500fcSDimitry Andric       if (AggregatedStmts.size() <= 1) {
1246bfef3995SDimitry Andric         if (!AggregatedStmts.empty()) {
1247bfef3995SDimitry Andric           CopyingValueRepresentation CVR(CGF);
1248bfef3995SDimitry Andric           CGF.EmitStmt(AggregatedStmts[0]);
1249bfef3995SDimitry Andric         }
1250809500fcSDimitry Andric         reset();
1251809500fcSDimitry Andric       }
1252809500fcSDimitry Andric 
1253809500fcSDimitry Andric       emitMemcpy();
1254809500fcSDimitry Andric       AggregatedStmts.clear();
1255809500fcSDimitry Andric     }
1256809500fcSDimitry Andric 
finish()1257809500fcSDimitry Andric     void finish() {
1258809500fcSDimitry Andric       emitAggregatedStmts();
1259809500fcSDimitry Andric     }
1260809500fcSDimitry Andric   };
126145b53394SDimitry Andric } // end anonymous namespace
1262809500fcSDimitry Andric 
isInitializerOfDynamicClass(const CXXCtorInitializer * BaseInit)126345b53394SDimitry Andric static bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit) {
126445b53394SDimitry Andric   const Type *BaseType = BaseInit->getBaseClass();
126545b53394SDimitry Andric   const auto *BaseClassDecl =
1266519fc96cSDimitry Andric       cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl());
126745b53394SDimitry Andric   return BaseClassDecl->isDynamicClass();
1268809500fcSDimitry Andric }
1269809500fcSDimitry Andric 
1270abe15e55SRoman Divacky /// EmitCtorPrologue - This routine generates necessary code to initialize
1271abe15e55SRoman Divacky /// base classes and non-static data members belonging to this constructor.
EmitCtorPrologue(const CXXConstructorDecl * CD,CXXCtorType CtorType,FunctionArgList & Args)1272abe15e55SRoman Divacky void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
1273d7279c4cSRoman Divacky                                        CXXCtorType CtorType,
1274d7279c4cSRoman Divacky                                        FunctionArgList &Args) {
127501af97d3SDimitry Andric   if (CD->isDelegatingConstructor())
127601af97d3SDimitry Andric     return EmitDelegatingCXXConstructorCall(CD, Args);
127701af97d3SDimitry Andric 
1278abe15e55SRoman Divacky   const CXXRecordDecl *ClassDecl = CD->getParent();
1279abe15e55SRoman Divacky 
1280809500fcSDimitry Andric   CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
1281abe15e55SRoman Divacky                                           E = CD->init_end();
1282abe15e55SRoman Divacky 
128322989816SDimitry Andric   // Virtual base initializers first, if any. They aren't needed if:
128422989816SDimitry Andric   // - This is a base ctor variant
128522989816SDimitry Andric   // - There are no vbases
128622989816SDimitry Andric   // - The class is abstract, so a complete object of it cannot be constructed
128722989816SDimitry Andric   //
128822989816SDimitry Andric   // The check for an abstract class is necessary because sema may not have
128922989816SDimitry Andric   // marked virtual base destructors referenced.
129022989816SDimitry Andric   bool ConstructVBases = CtorType != Ctor_Base &&
129122989816SDimitry Andric                          ClassDecl->getNumVBases() != 0 &&
129222989816SDimitry Andric                          !ClassDecl->isAbstract();
129322989816SDimitry Andric 
129422989816SDimitry Andric   // In the Microsoft C++ ABI, there are no constructor variants. Instead, the
129522989816SDimitry Andric   // constructor of a class with virtual bases takes an additional parameter to
129622989816SDimitry Andric   // conditionally construct the virtual bases. Emit that check here.
12979f4dbff6SDimitry Andric   llvm::BasicBlock *BaseCtorContinueBB = nullptr;
129822989816SDimitry Andric   if (ConstructVBases &&
1299809500fcSDimitry Andric       !CGM.getTarget().getCXXABI().hasConstructorVariants()) {
1300bfef3995SDimitry Andric     BaseCtorContinueBB =
1301bfef3995SDimitry Andric         CGM.getCXXABI().EmitCtorCompleteObjectHandler(*this, ClassDecl);
1302809500fcSDimitry Andric     assert(BaseCtorContinueBB);
130329cafa66SDimitry Andric   }
1304809500fcSDimitry Andric 
1305809500fcSDimitry Andric   for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
130622989816SDimitry Andric     if (!ConstructVBases)
130722989816SDimitry Andric       continue;
1308b1c73532SDimitry Andric     SaveAndRestore ThisRAII(CXXThisValue);
130945b53394SDimitry Andric     if (CGM.getCodeGenOpts().StrictVTablePointers &&
131045b53394SDimitry Andric         CGM.getCodeGenOpts().OptimizationLevel > 0 &&
131145b53394SDimitry Andric         isInitializerOfDynamicClass(*B))
131248675466SDimitry Andric       CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
131322989816SDimitry Andric     EmitBaseInitializer(*this, ClassDecl, *B);
1314809500fcSDimitry Andric   }
1315809500fcSDimitry Andric 
1316809500fcSDimitry Andric   if (BaseCtorContinueBB) {
1317809500fcSDimitry Andric     // Complete object handler should continue to the remaining initializers.
1318809500fcSDimitry Andric     Builder.CreateBr(BaseCtorContinueBB);
1319809500fcSDimitry Andric     EmitBlock(BaseCtorContinueBB);
1320809500fcSDimitry Andric   }
1321809500fcSDimitry Andric 
1322809500fcSDimitry Andric   // Then, non-virtual base initializers.
1323809500fcSDimitry Andric   for (; B != E && (*B)->isBaseInitializer(); B++) {
1324809500fcSDimitry Andric     assert(!(*B)->isBaseVirtual());
1325b1c73532SDimitry Andric     SaveAndRestore ThisRAII(CXXThisValue);
132645b53394SDimitry Andric     if (CGM.getCodeGenOpts().StrictVTablePointers &&
132745b53394SDimitry Andric         CGM.getCodeGenOpts().OptimizationLevel > 0 &&
132845b53394SDimitry Andric         isInitializerOfDynamicClass(*B))
132948675466SDimitry Andric       CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
133022989816SDimitry Andric     EmitBaseInitializer(*this, ClassDecl, *B);
1331abe15e55SRoman Divacky   }
1332abe15e55SRoman Divacky 
133311d2b2d2SRoman Divacky   InitializeVTablePointers(ClassDecl);
1334ecb7e5c8SRoman Divacky 
1335809500fcSDimitry Andric   // And finally, initialize class members.
133645b53394SDimitry Andric   FieldConstructionScope FCS(*this, LoadCXXThisAddress());
1337809500fcSDimitry Andric   ConstructorMemcpyizer CM(*this, CD, Args);
1338809500fcSDimitry Andric   for (; B != E; B++) {
1339809500fcSDimitry Andric     CXXCtorInitializer *Member = (*B);
1340809500fcSDimitry Andric     assert(!Member->isBaseInitializer());
1341809500fcSDimitry Andric     assert(Member->isAnyMemberInitializer() &&
1342809500fcSDimitry Andric            "Delegating initializer on non-delegating constructor");
1343809500fcSDimitry Andric     CM.addMemberInitializer(Member);
1344809500fcSDimitry Andric   }
1345809500fcSDimitry Andric   CM.finish();
1346ecb7e5c8SRoman Divacky }
1347abe15e55SRoman Divacky 
134829cafa66SDimitry Andric static bool
134929cafa66SDimitry Andric FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field);
135029cafa66SDimitry Andric 
135129cafa66SDimitry Andric static bool
HasTrivialDestructorBody(ASTContext & Context,const CXXRecordDecl * BaseClassDecl,const CXXRecordDecl * MostDerivedClassDecl)135229cafa66SDimitry Andric HasTrivialDestructorBody(ASTContext &Context,
135329cafa66SDimitry Andric                          const CXXRecordDecl *BaseClassDecl,
135429cafa66SDimitry Andric                          const CXXRecordDecl *MostDerivedClassDecl)
135529cafa66SDimitry Andric {
135629cafa66SDimitry Andric   // If the destructor is trivial we don't have to check anything else.
135729cafa66SDimitry Andric   if (BaseClassDecl->hasTrivialDestructor())
135829cafa66SDimitry Andric     return true;
135929cafa66SDimitry Andric 
136029cafa66SDimitry Andric   if (!BaseClassDecl->getDestructor()->hasTrivialBody())
136129cafa66SDimitry Andric     return false;
136229cafa66SDimitry Andric 
136329cafa66SDimitry Andric   // Check fields.
13649f4dbff6SDimitry Andric   for (const auto *Field : BaseClassDecl->fields())
136529cafa66SDimitry Andric     if (!FieldHasTrivialDestructorBody(Context, Field))
136629cafa66SDimitry Andric       return false;
136729cafa66SDimitry Andric 
136829cafa66SDimitry Andric   // Check non-virtual bases.
13699f4dbff6SDimitry Andric   for (const auto &I : BaseClassDecl->bases()) {
13709f4dbff6SDimitry Andric     if (I.isVirtual())
137129cafa66SDimitry Andric       continue;
137229cafa66SDimitry Andric 
137329cafa66SDimitry Andric     const CXXRecordDecl *NonVirtualBase =
13749f4dbff6SDimitry Andric       cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
137529cafa66SDimitry Andric     if (!HasTrivialDestructorBody(Context, NonVirtualBase,
137629cafa66SDimitry Andric                                   MostDerivedClassDecl))
137729cafa66SDimitry Andric       return false;
137829cafa66SDimitry Andric   }
137929cafa66SDimitry Andric 
138029cafa66SDimitry Andric   if (BaseClassDecl == MostDerivedClassDecl) {
138129cafa66SDimitry Andric     // Check virtual bases.
13829f4dbff6SDimitry Andric     for (const auto &I : BaseClassDecl->vbases()) {
138329cafa66SDimitry Andric       const CXXRecordDecl *VirtualBase =
13849f4dbff6SDimitry Andric         cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
138529cafa66SDimitry Andric       if (!HasTrivialDestructorBody(Context, VirtualBase,
138629cafa66SDimitry Andric                                     MostDerivedClassDecl))
138729cafa66SDimitry Andric         return false;
138829cafa66SDimitry Andric     }
138929cafa66SDimitry Andric   }
139029cafa66SDimitry Andric 
139129cafa66SDimitry Andric   return true;
139229cafa66SDimitry Andric }
139329cafa66SDimitry Andric 
139429cafa66SDimitry Andric static bool
FieldHasTrivialDestructorBody(ASTContext & Context,const FieldDecl * Field)139529cafa66SDimitry Andric FieldHasTrivialDestructorBody(ASTContext &Context,
139629cafa66SDimitry Andric                                           const FieldDecl *Field)
139729cafa66SDimitry Andric {
139829cafa66SDimitry Andric   QualType FieldBaseElementType = Context.getBaseElementType(Field->getType());
139929cafa66SDimitry Andric 
140029cafa66SDimitry Andric   const RecordType *RT = FieldBaseElementType->getAs<RecordType>();
140129cafa66SDimitry Andric   if (!RT)
140229cafa66SDimitry Andric     return true;
140329cafa66SDimitry Andric 
140429cafa66SDimitry Andric   CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
1405c192b3dcSDimitry Andric 
1406c192b3dcSDimitry Andric   // The destructor for an implicit anonymous union member is never invoked.
1407c192b3dcSDimitry Andric   if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
1408ac9a064cSDimitry Andric     return true;
1409c192b3dcSDimitry Andric 
141029cafa66SDimitry Andric   return HasTrivialDestructorBody(Context, FieldClassDecl, FieldClassDecl);
141129cafa66SDimitry Andric }
141229cafa66SDimitry Andric 
141329cafa66SDimitry Andric /// CanSkipVTablePointerInitialization - Check whether we need to initialize
141429cafa66SDimitry Andric /// any vtable pointers before calling this destructor.
CanSkipVTablePointerInitialization(CodeGenFunction & CGF,const CXXDestructorDecl * Dtor)141545b53394SDimitry Andric static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF,
141629cafa66SDimitry Andric                                                const CXXDestructorDecl *Dtor) {
141745b53394SDimitry Andric   const CXXRecordDecl *ClassDecl = Dtor->getParent();
141845b53394SDimitry Andric   if (!ClassDecl->isDynamicClass())
141945b53394SDimitry Andric     return true;
142045b53394SDimitry Andric 
1421c0981da4SDimitry Andric   // For a final class, the vtable pointer is known to already point to the
1422c0981da4SDimitry Andric   // class's vtable.
1423c0981da4SDimitry Andric   if (ClassDecl->isEffectivelyFinal())
1424c0981da4SDimitry Andric     return true;
1425c0981da4SDimitry Andric 
142629cafa66SDimitry Andric   if (!Dtor->hasTrivialBody())
142729cafa66SDimitry Andric     return false;
142829cafa66SDimitry Andric 
142929cafa66SDimitry Andric   // Check the fields.
14309f4dbff6SDimitry Andric   for (const auto *Field : ClassDecl->fields())
143145b53394SDimitry Andric     if (!FieldHasTrivialDestructorBody(CGF.getContext(), Field))
143229cafa66SDimitry Andric       return false;
143329cafa66SDimitry Andric 
143429cafa66SDimitry Andric   return true;
143529cafa66SDimitry Andric }
143629cafa66SDimitry Andric 
143779ade4e0SRoman Divacky /// EmitDestructorBody - Emits the body of the current destructor.
EmitDestructorBody(FunctionArgList & Args)143879ade4e0SRoman Divacky void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
143979ade4e0SRoman Divacky   const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl());
144079ade4e0SRoman Divacky   CXXDtorType DtorType = CurGD.getDtorType();
144179ade4e0SRoman Divacky 
14427442d6faSDimitry Andric   // For an abstract class, non-base destructors are never used (and can't
14437442d6faSDimitry Andric   // be emitted in general, because vbase dtors may not have been validated
14447442d6faSDimitry Andric   // by Sema), but the Itanium ABI doesn't make them optional and Clang may
14457442d6faSDimitry Andric   // in fact emit references to them from other compilations, so emit them
14467442d6faSDimitry Andric   // as functions containing a trap instruction.
14477442d6faSDimitry Andric   if (DtorType != Dtor_Base && Dtor->getParent()->isAbstract()) {
14487442d6faSDimitry Andric     llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
14497442d6faSDimitry Andric     TrapCall->setDoesNotReturn();
14507442d6faSDimitry Andric     TrapCall->setDoesNotThrow();
14517442d6faSDimitry Andric     Builder.CreateUnreachable();
14527442d6faSDimitry Andric     Builder.ClearInsertionPoint();
14537442d6faSDimitry Andric     return;
14547442d6faSDimitry Andric   }
14557442d6faSDimitry Andric 
14565e20cdd8SDimitry Andric   Stmt *Body = Dtor->getBody();
1457aca2e42cSDimitry Andric   if (Body) {
14585e20cdd8SDimitry Andric     incrementProfileCounter(Body);
1459aca2e42cSDimitry Andric     maybeCreateMCDCCondBitmap();
1460aca2e42cSDimitry Andric   }
14615e20cdd8SDimitry Andric 
14623d1dcd9bSDimitry Andric   // The call to operator delete in a deleting destructor happens
14633d1dcd9bSDimitry Andric   // outside of the function-try-block, which means it's always
14643d1dcd9bSDimitry Andric   // possible to delegate the destructor body to the complete
14653d1dcd9bSDimitry Andric   // destructor.  Do so.
14663d1dcd9bSDimitry Andric   if (DtorType == Dtor_Deleting) {
1467461a67faSDimitry Andric     RunCleanupsScope DtorEpilogue(*this);
14683d1dcd9bSDimitry Andric     EnterDtorCleanups(Dtor, Dtor_Deleting);
146922989816SDimitry Andric     if (HaveInsertPoint()) {
1470b1c73532SDimitry Andric       QualType ThisTy = Dtor->getFunctionObjectParameterType();
14713d1dcd9bSDimitry Andric       EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
147222989816SDimitry Andric                             /*Delegating=*/false, LoadCXXThisAddress(), ThisTy);
147322989816SDimitry Andric     }
14743d1dcd9bSDimitry Andric     return;
14753d1dcd9bSDimitry Andric   }
14763d1dcd9bSDimitry Andric 
147779ade4e0SRoman Divacky   // If the body is a function-try-block, enter the try before
14783d1dcd9bSDimitry Andric   // anything else.
1479ac9a064cSDimitry Andric   bool isTryBody = isa_and_nonnull<CXXTryStmt>(Body);
148079ade4e0SRoman Divacky   if (isTryBody)
14814ba67500SRoman Divacky     EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true);
148206d4ba38SDimitry Andric   EmitAsanPrologueOrEpilogue(false);
148379ade4e0SRoman Divacky 
14843d1dcd9bSDimitry Andric   // Enter the epilogue cleanups.
14853d1dcd9bSDimitry Andric   RunCleanupsScope DtorEpilogue(*this);
148679ade4e0SRoman Divacky 
148779ade4e0SRoman Divacky   // If this is the complete variant, just invoke the base variant;
148879ade4e0SRoman Divacky   // the epilogue will destruct the virtual bases.  But we can't do
148979ade4e0SRoman Divacky   // this optimization if the body is a function-try-block, because
1490bfef3995SDimitry Andric   // we'd introduce *two* handler blocks.  In the Microsoft ABI, we
1491bfef3995SDimitry Andric   // always delegate because we might not have a definition in this TU.
14923d1dcd9bSDimitry Andric   switch (DtorType) {
14937442d6faSDimitry Andric   case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT");
14943d1dcd9bSDimitry Andric   case Dtor_Deleting: llvm_unreachable("already handled deleting case");
14953d1dcd9bSDimitry Andric 
14963d1dcd9bSDimitry Andric   case Dtor_Complete:
1497bfef3995SDimitry Andric     assert((Body || getTarget().getCXXABI().isMicrosoft()) &&
1498bfef3995SDimitry Andric            "can't emit a dtor without a body for non-Microsoft ABIs");
1499bfef3995SDimitry Andric 
15003d1dcd9bSDimitry Andric     // Enter the cleanup scopes for virtual bases.
15013d1dcd9bSDimitry Andric     EnterDtorCleanups(Dtor, Dtor_Complete);
15023d1dcd9bSDimitry Andric 
1503bfef3995SDimitry Andric     if (!isTryBody) {
1504b1c73532SDimitry Andric       QualType ThisTy = Dtor->getFunctionObjectParameterType();
15050883ccd9SRoman Divacky       EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false,
150622989816SDimitry Andric                             /*Delegating=*/false, LoadCXXThisAddress(), ThisTy);
15073d1dcd9bSDimitry Andric       break;
150879ade4e0SRoman Divacky     }
15097442d6faSDimitry Andric 
15103d1dcd9bSDimitry Andric     // Fallthrough: act like we're in the base variant.
1511e3b55780SDimitry Andric     [[fallthrough]];
151279ade4e0SRoman Divacky 
15133d1dcd9bSDimitry Andric   case Dtor_Base:
1514bfef3995SDimitry Andric     assert(Body);
1515bfef3995SDimitry Andric 
15163d1dcd9bSDimitry Andric     // Enter the cleanup scopes for fields and non-virtual bases.
15173d1dcd9bSDimitry Andric     EnterDtorCleanups(Dtor, Dtor_Base);
15183d1dcd9bSDimitry Andric 
15193d1dcd9bSDimitry Andric     // Initialize the vtable pointers before entering the body.
152045b53394SDimitry Andric     if (!CanSkipVTablePointerInitialization(*this, Dtor)) {
152148675466SDimitry Andric       // Insert the llvm.launder.invariant.group intrinsic before initializing
152245b53394SDimitry Andric       // the vptrs to cancel any previous assumptions we might have made.
152345b53394SDimitry Andric       if (CGM.getCodeGenOpts().StrictVTablePointers &&
152445b53394SDimitry Andric           CGM.getCodeGenOpts().OptimizationLevel > 0)
152548675466SDimitry Andric         CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
15263d1dcd9bSDimitry Andric       InitializeVTablePointers(Dtor->getParent());
152745b53394SDimitry Andric     }
15283d1dcd9bSDimitry Andric 
15293d1dcd9bSDimitry Andric     if (isTryBody)
153079ade4e0SRoman Divacky       EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
153179ade4e0SRoman Divacky     else if (Body)
153279ade4e0SRoman Divacky       EmitStmt(Body);
153379ade4e0SRoman Divacky     else {
153479ade4e0SRoman Divacky       assert(Dtor->isImplicit() && "bodyless dtor not implicit");
153579ade4e0SRoman Divacky       // nothing to do besides what's in the epilogue
153679ade4e0SRoman Divacky     }
1537bca07a45SDimitry Andric     // -fapple-kext must inline any call to this dtor into
1538bca07a45SDimitry Andric     // the caller's body.
153913cc256eSDimitry Andric     if (getLangOpts().AppleKext)
1540809500fcSDimitry Andric       CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
154145b53394SDimitry Andric 
15423d1dcd9bSDimitry Andric     break;
15433d1dcd9bSDimitry Andric   }
154479ade4e0SRoman Divacky 
15453d1dcd9bSDimitry Andric   // Jump out through the epilogue cleanups.
15463d1dcd9bSDimitry Andric   DtorEpilogue.ForceCleanup();
154779ade4e0SRoman Divacky 
154879ade4e0SRoman Divacky   // Exit the try if applicable.
154979ade4e0SRoman Divacky   if (isTryBody)
15504ba67500SRoman Divacky     ExitCXXTryStmt(*cast<CXXTryStmt>(Body), true);
155179ade4e0SRoman Divacky }
155279ade4e0SRoman Divacky 
emitImplicitAssignmentOperatorBody(FunctionArgList & Args)1553809500fcSDimitry Andric void CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args) {
1554809500fcSDimitry Andric   const CXXMethodDecl *AssignOp = cast<CXXMethodDecl>(CurGD.getDecl());
1555809500fcSDimitry Andric   const Stmt *RootS = AssignOp->getBody();
1556809500fcSDimitry Andric   assert(isa<CompoundStmt>(RootS) &&
1557809500fcSDimitry Andric          "Body of an implicit assignment operator should be compound stmt.");
1558809500fcSDimitry Andric   const CompoundStmt *RootCS = cast<CompoundStmt>(RootS);
1559809500fcSDimitry Andric 
1560809500fcSDimitry Andric   LexicalScope Scope(*this, RootCS->getSourceRange());
1561809500fcSDimitry Andric 
15622b6b257fSDimitry Andric   incrementProfileCounter(RootCS);
1563aca2e42cSDimitry Andric   maybeCreateMCDCCondBitmap();
1564809500fcSDimitry Andric   AssignmentMemcpyizer AM(*this, AssignOp, Args);
15659f4dbff6SDimitry Andric   for (auto *I : RootCS->body())
15669f4dbff6SDimitry Andric     AM.emitAssignment(I);
1567809500fcSDimitry Andric   AM.finish();
1568809500fcSDimitry Andric }
1569809500fcSDimitry Andric 
15703d1dcd9bSDimitry Andric namespace {
LoadThisForDtorDelete(CodeGenFunction & CGF,const CXXDestructorDecl * DD)1571461a67faSDimitry Andric   llvm::Value *LoadThisForDtorDelete(CodeGenFunction &CGF,
1572461a67faSDimitry Andric                                      const CXXDestructorDecl *DD) {
1573461a67faSDimitry Andric     if (Expr *ThisArg = DD->getOperatorDeleteThisArg())
1574461a67faSDimitry Andric       return CGF.EmitScalarExpr(ThisArg);
1575461a67faSDimitry Andric     return CGF.LoadCXXThis();
1576461a67faSDimitry Andric   }
1577461a67faSDimitry Andric 
15783d1dcd9bSDimitry Andric   /// Call the operator delete associated with the current destructor.
157945b53394SDimitry Andric   struct CallDtorDelete final : EHScopeStack::Cleanup {
CallDtorDelete__anonf1d54d130411::CallDtorDelete15803d1dcd9bSDimitry Andric     CallDtorDelete() {}
15813d1dcd9bSDimitry Andric 
Emit__anonf1d54d130411::CallDtorDelete15829f4dbff6SDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
15833d1dcd9bSDimitry Andric       const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl);
15843d1dcd9bSDimitry Andric       const CXXRecordDecl *ClassDecl = Dtor->getParent();
1585461a67faSDimitry Andric       CGF.EmitDeleteCall(Dtor->getOperatorDelete(),
1586461a67faSDimitry Andric                          LoadThisForDtorDelete(CGF, Dtor),
15873d1dcd9bSDimitry Andric                          CGF.getContext().getTagDeclType(ClassDecl));
15883d1dcd9bSDimitry Andric     }
15893d1dcd9bSDimitry Andric   };
15903d1dcd9bSDimitry Andric 
EmitConditionalDtorDeleteCall(CodeGenFunction & CGF,llvm::Value * ShouldDeleteCondition,bool ReturnAfterDelete)1591461a67faSDimitry Andric   void EmitConditionalDtorDeleteCall(CodeGenFunction &CGF,
1592461a67faSDimitry Andric                                      llvm::Value *ShouldDeleteCondition,
1593461a67faSDimitry Andric                                      bool ReturnAfterDelete) {
1594461a67faSDimitry Andric     llvm::BasicBlock *callDeleteBB = CGF.createBasicBlock("dtor.call_delete");
1595461a67faSDimitry Andric     llvm::BasicBlock *continueBB = CGF.createBasicBlock("dtor.continue");
1596461a67faSDimitry Andric     llvm::Value *ShouldCallDelete
1597461a67faSDimitry Andric       = CGF.Builder.CreateIsNull(ShouldDeleteCondition);
1598461a67faSDimitry Andric     CGF.Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
1599461a67faSDimitry Andric 
1600461a67faSDimitry Andric     CGF.EmitBlock(callDeleteBB);
1601461a67faSDimitry Andric     const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl);
1602461a67faSDimitry Andric     const CXXRecordDecl *ClassDecl = Dtor->getParent();
1603461a67faSDimitry Andric     CGF.EmitDeleteCall(Dtor->getOperatorDelete(),
1604461a67faSDimitry Andric                        LoadThisForDtorDelete(CGF, Dtor),
1605461a67faSDimitry Andric                        CGF.getContext().getTagDeclType(ClassDecl));
1606461a67faSDimitry Andric     assert(Dtor->getOperatorDelete()->isDestroyingOperatorDelete() ==
1607461a67faSDimitry Andric                ReturnAfterDelete &&
1608461a67faSDimitry Andric            "unexpected value for ReturnAfterDelete");
1609461a67faSDimitry Andric     if (ReturnAfterDelete)
1610461a67faSDimitry Andric       CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
1611461a67faSDimitry Andric     else
1612461a67faSDimitry Andric       CGF.Builder.CreateBr(continueBB);
1613461a67faSDimitry Andric 
1614461a67faSDimitry Andric     CGF.EmitBlock(continueBB);
1615461a67faSDimitry Andric   }
1616461a67faSDimitry Andric 
161745b53394SDimitry Andric   struct CallDtorDeleteConditional final : EHScopeStack::Cleanup {
1618809500fcSDimitry Andric     llvm::Value *ShouldDeleteCondition;
16192b6b257fSDimitry Andric 
1620809500fcSDimitry Andric   public:
CallDtorDeleteConditional__anonf1d54d130411::CallDtorDeleteConditional1621809500fcSDimitry Andric     CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition)
1622809500fcSDimitry Andric         : ShouldDeleteCondition(ShouldDeleteCondition) {
16239f4dbff6SDimitry Andric       assert(ShouldDeleteCondition != nullptr);
1624809500fcSDimitry Andric     }
1625809500fcSDimitry Andric 
Emit__anonf1d54d130411::CallDtorDeleteConditional16269f4dbff6SDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
1627461a67faSDimitry Andric       EmitConditionalDtorDeleteCall(CGF, ShouldDeleteCondition,
1628461a67faSDimitry Andric                                     /*ReturnAfterDelete*/false);
1629809500fcSDimitry Andric     }
1630809500fcSDimitry Andric   };
1631809500fcSDimitry Andric 
163245b53394SDimitry Andric   class DestroyField  final : public EHScopeStack::Cleanup {
1633180abc3dSDimitry Andric     const FieldDecl *field;
1634dbe13110SDimitry Andric     CodeGenFunction::Destroyer *destroyer;
1635180abc3dSDimitry Andric     bool useEHCleanupForArray;
16363d1dcd9bSDimitry Andric 
1637180abc3dSDimitry Andric   public:
DestroyField(const FieldDecl * field,CodeGenFunction::Destroyer * destroyer,bool useEHCleanupForArray)1638180abc3dSDimitry Andric     DestroyField(const FieldDecl *field, CodeGenFunction::Destroyer *destroyer,
1639180abc3dSDimitry Andric                  bool useEHCleanupForArray)
1640dbe13110SDimitry Andric         : field(field), destroyer(destroyer),
1641180abc3dSDimitry Andric           useEHCleanupForArray(useEHCleanupForArray) {}
16423d1dcd9bSDimitry Andric 
Emit(CodeGenFunction & CGF,Flags flags)16439f4dbff6SDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
1644180abc3dSDimitry Andric       // Find the address of the field.
164545b53394SDimitry Andric       Address thisValue = CGF.LoadCXXThisAddress();
16466b9a6e39SDimitry Andric       QualType RecordTy = CGF.getContext().getTagDeclType(field->getParent());
16476b9a6e39SDimitry Andric       LValue ThisLV = CGF.MakeAddrLValue(thisValue, RecordTy);
16486b9a6e39SDimitry Andric       LValue LV = CGF.EmitLValueForField(ThisLV, field);
1649180abc3dSDimitry Andric       assert(LV.isSimple());
16503d1dcd9bSDimitry Andric 
1651ac9a064cSDimitry Andric       CGF.emitDestroy(LV.getAddress(), field->getType(), destroyer,
1652180abc3dSDimitry Andric                       flags.isForNormalCleanup() && useEHCleanupForArray);
16533d1dcd9bSDimitry Andric     }
16543d1dcd9bSDimitry Andric   };
165545b53394SDimitry Andric 
1656e3b55780SDimitry Andric   class DeclAsInlineDebugLocation {
1657e3b55780SDimitry Andric     CGDebugInfo *DI;
1658e3b55780SDimitry Andric     llvm::MDNode *InlinedAt;
1659e3b55780SDimitry Andric     std::optional<ApplyDebugLocation> Location;
1660e3b55780SDimitry Andric 
1661e3b55780SDimitry Andric   public:
DeclAsInlineDebugLocation(CodeGenFunction & CGF,const NamedDecl & Decl)1662e3b55780SDimitry Andric     DeclAsInlineDebugLocation(CodeGenFunction &CGF, const NamedDecl &Decl)
1663e3b55780SDimitry Andric         : DI(CGF.getDebugInfo()) {
1664e3b55780SDimitry Andric       if (!DI)
1665e3b55780SDimitry Andric         return;
1666e3b55780SDimitry Andric       InlinedAt = DI->getInlinedAt();
1667e3b55780SDimitry Andric       DI->setInlinedAt(CGF.Builder.getCurrentDebugLocation());
1668e3b55780SDimitry Andric       Location.emplace(CGF, Decl.getLocation());
1669e3b55780SDimitry Andric     }
1670e3b55780SDimitry Andric 
~DeclAsInlineDebugLocation()1671e3b55780SDimitry Andric     ~DeclAsInlineDebugLocation() {
1672e3b55780SDimitry Andric       if (!DI)
1673e3b55780SDimitry Andric         return;
1674e3b55780SDimitry Andric       Location.reset();
1675e3b55780SDimitry Andric       DI->setInlinedAt(InlinedAt);
1676e3b55780SDimitry Andric     }
1677e3b55780SDimitry Andric   };
1678e3b55780SDimitry Andric 
EmitSanitizerDtorCallback(CodeGenFunction & CGF,StringRef Name,llvm::Value * Ptr,std::optional<CharUnits::QuantityType> PoisonSize={})1679e3b55780SDimitry Andric   static void EmitSanitizerDtorCallback(
1680e3b55780SDimitry Andric       CodeGenFunction &CGF, StringRef Name, llvm::Value *Ptr,
1681e3b55780SDimitry Andric       std::optional<CharUnits::QuantityType> PoisonSize = {}) {
1682461a67faSDimitry Andric     CodeGenFunction::SanitizerScope SanScope(&CGF);
168345b53394SDimitry Andric     // Pass in void pointer and size of region as arguments to runtime
168445b53394SDimitry Andric     // function
1685b1c73532SDimitry Andric     SmallVector<llvm::Value *, 2> Args = {Ptr};
1686e3b55780SDimitry Andric     SmallVector<llvm::Type *, 2> ArgTypes = {CGF.VoidPtrTy};
168745b53394SDimitry Andric 
1688e3b55780SDimitry Andric     if (PoisonSize.has_value()) {
1689e3b55780SDimitry Andric       Args.emplace_back(llvm::ConstantInt::get(CGF.SizeTy, *PoisonSize));
1690e3b55780SDimitry Andric       ArgTypes.emplace_back(CGF.SizeTy);
1691e3b55780SDimitry Andric     }
169245b53394SDimitry Andric 
169345b53394SDimitry Andric     llvm::FunctionType *FnType =
169445b53394SDimitry Andric         llvm::FunctionType::get(CGF.VoidTy, ArgTypes, false);
1695e3b55780SDimitry Andric     llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction(FnType, Name);
1696e3b55780SDimitry Andric 
169745b53394SDimitry Andric     CGF.EmitNounwindRuntimeCall(Fn, Args);
16983d1dcd9bSDimitry Andric   }
16993d1dcd9bSDimitry Andric 
1700e3b55780SDimitry Andric   static void
EmitSanitizerDtorFieldsCallback(CodeGenFunction & CGF,llvm::Value * Ptr,CharUnits::QuantityType PoisonSize)1701e3b55780SDimitry Andric   EmitSanitizerDtorFieldsCallback(CodeGenFunction &CGF, llvm::Value *Ptr,
1702e3b55780SDimitry Andric                                   CharUnits::QuantityType PoisonSize) {
1703e3b55780SDimitry Andric     EmitSanitizerDtorCallback(CGF, "__sanitizer_dtor_callback_fields", Ptr,
1704e3b55780SDimitry Andric                               PoisonSize);
1705e3b55780SDimitry Andric   }
1706e3b55780SDimitry Andric 
1707145449b1SDimitry Andric   /// Poison base class with a trivial destructor.
1708145449b1SDimitry Andric   struct SanitizeDtorTrivialBase final : EHScopeStack::Cleanup {
1709145449b1SDimitry Andric     const CXXRecordDecl *BaseClass;
1710145449b1SDimitry Andric     bool BaseIsVirtual;
SanitizeDtorTrivialBase__anonf1d54d130411::SanitizeDtorTrivialBase1711145449b1SDimitry Andric     SanitizeDtorTrivialBase(const CXXRecordDecl *Base, bool BaseIsVirtual)
1712145449b1SDimitry Andric         : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {}
1713145449b1SDimitry Andric 
Emit__anonf1d54d130411::SanitizeDtorTrivialBase1714145449b1SDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
1715145449b1SDimitry Andric       const CXXRecordDecl *DerivedClass =
1716145449b1SDimitry Andric           cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent();
1717145449b1SDimitry Andric 
1718145449b1SDimitry Andric       Address Addr = CGF.GetAddressOfDirectBaseInCompleteClass(
1719145449b1SDimitry Andric           CGF.LoadCXXThisAddress(), DerivedClass, BaseClass, BaseIsVirtual);
1720145449b1SDimitry Andric 
1721145449b1SDimitry Andric       const ASTRecordLayout &BaseLayout =
1722145449b1SDimitry Andric           CGF.getContext().getASTRecordLayout(BaseClass);
1723145449b1SDimitry Andric       CharUnits BaseSize = BaseLayout.getSize();
1724145449b1SDimitry Andric 
1725145449b1SDimitry Andric       if (!BaseSize.isPositive())
1726145449b1SDimitry Andric         return;
1727145449b1SDimitry Andric 
1728e3b55780SDimitry Andric       // Use the base class declaration location as inline DebugLocation. All
1729e3b55780SDimitry Andric       // fields of the class are destroyed.
1730e3b55780SDimitry Andric       DeclAsInlineDebugLocation InlineHere(CGF, *BaseClass);
1731ac9a064cSDimitry Andric       EmitSanitizerDtorFieldsCallback(CGF, Addr.emitRawPointer(CGF),
1732e3b55780SDimitry Andric                                       BaseSize.getQuantity());
1733145449b1SDimitry Andric 
1734145449b1SDimitry Andric       // Prevent the current stack frame from disappearing from the stack trace.
1735145449b1SDimitry Andric       CGF.CurFn->addFnAttr("disable-tail-calls", "true");
1736145449b1SDimitry Andric     }
1737145449b1SDimitry Andric   };
1738145449b1SDimitry Andric 
1739145449b1SDimitry Andric   class SanitizeDtorFieldRange final : public EHScopeStack::Cleanup {
174045b53394SDimitry Andric     const CXXDestructorDecl *Dtor;
1741145449b1SDimitry Andric     unsigned StartIndex;
1742145449b1SDimitry Andric     unsigned EndIndex;
174345b53394SDimitry Andric 
174445b53394SDimitry Andric   public:
SanitizeDtorFieldRange(const CXXDestructorDecl * Dtor,unsigned StartIndex,unsigned EndIndex)1745145449b1SDimitry Andric     SanitizeDtorFieldRange(const CXXDestructorDecl *Dtor, unsigned StartIndex,
1746145449b1SDimitry Andric                            unsigned EndIndex)
1747145449b1SDimitry Andric         : Dtor(Dtor), StartIndex(StartIndex), EndIndex(EndIndex) {}
174845b53394SDimitry Andric 
174945b53394SDimitry Andric     // Generate function call for handling object poisoning.
175045b53394SDimitry Andric     // Disables tail call elimination, to prevent the current stack frame
175145b53394SDimitry Andric     // from disappearing from the stack trace.
Emit(CodeGenFunction & CGF,Flags flags)175245b53394SDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
1753145449b1SDimitry Andric       const ASTContext &Context = CGF.getContext();
175445b53394SDimitry Andric       const ASTRecordLayout &Layout =
175545b53394SDimitry Andric           Context.getASTRecordLayout(Dtor->getParent());
175645b53394SDimitry Andric 
1757145449b1SDimitry Andric       // It's a first trivial field so it should be at the begining of a char,
1758b60736ecSDimitry Andric       // still round up start offset just in case.
1759145449b1SDimitry Andric       CharUnits PoisonStart = Context.toCharUnitsFromBits(
1760145449b1SDimitry Andric           Layout.getFieldOffset(StartIndex) + Context.getCharWidth() - 1);
1761b60736ecSDimitry Andric       llvm::ConstantInt *OffsetSizePtr =
1762b60736ecSDimitry Andric           llvm::ConstantInt::get(CGF.SizeTy, PoisonStart.getQuantity());
176345b53394SDimitry Andric 
1764b1c73532SDimitry Andric       llvm::Value *OffsetPtr =
1765b1c73532SDimitry Andric           CGF.Builder.CreateGEP(CGF.Int8Ty, CGF.LoadCXXThis(), OffsetSizePtr);
176645b53394SDimitry Andric 
1767b60736ecSDimitry Andric       CharUnits PoisonEnd;
1768145449b1SDimitry Andric       if (EndIndex >= Layout.getFieldCount()) {
1769b60736ecSDimitry Andric         PoisonEnd = Layout.getNonVirtualSize();
177045b53394SDimitry Andric       } else {
1771b60736ecSDimitry Andric         PoisonEnd =
1772145449b1SDimitry Andric             Context.toCharUnitsFromBits(Layout.getFieldOffset(EndIndex));
177345b53394SDimitry Andric       }
1774b60736ecSDimitry Andric       CharUnits PoisonSize = PoisonEnd - PoisonStart;
1775b60736ecSDimitry Andric       if (!PoisonSize.isPositive())
177645b53394SDimitry Andric         return;
177745b53394SDimitry Andric 
1778e3b55780SDimitry Andric       // Use the top field declaration location as inline DebugLocation.
1779e3b55780SDimitry Andric       DeclAsInlineDebugLocation InlineHere(
1780e3b55780SDimitry Andric           CGF, **std::next(Dtor->getParent()->field_begin(), StartIndex));
1781e3b55780SDimitry Andric       EmitSanitizerDtorFieldsCallback(CGF, OffsetPtr, PoisonSize.getQuantity());
1782145449b1SDimitry Andric 
1783145449b1SDimitry Andric       // Prevent the current stack frame from disappearing from the stack trace.
1784145449b1SDimitry Andric       CGF.CurFn->addFnAttr("disable-tail-calls", "true");
178545b53394SDimitry Andric     }
178645b53394SDimitry Andric   };
178745b53394SDimitry Andric 
178845b53394SDimitry Andric  class SanitizeDtorVTable final : public EHScopeStack::Cleanup {
178945b53394SDimitry Andric     const CXXDestructorDecl *Dtor;
179045b53394SDimitry Andric 
179145b53394SDimitry Andric   public:
SanitizeDtorVTable(const CXXDestructorDecl * Dtor)179245b53394SDimitry Andric     SanitizeDtorVTable(const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
179345b53394SDimitry Andric 
179445b53394SDimitry Andric     // Generate function call for handling vtable pointer poisoning.
Emit(CodeGenFunction & CGF,Flags flags)179545b53394SDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
179645b53394SDimitry Andric       assert(Dtor->getParent()->isDynamicClass());
179745b53394SDimitry Andric       (void)Dtor;
179845b53394SDimitry Andric       // Poison vtable and vtable ptr if they exist for this class.
179945b53394SDimitry Andric       llvm::Value *VTablePtr = CGF.LoadCXXThis();
180045b53394SDimitry Andric 
180145b53394SDimitry Andric       // Pass in void pointer and size of region as arguments to runtime
180245b53394SDimitry Andric       // function
1803e3b55780SDimitry Andric       EmitSanitizerDtorCallback(CGF, "__sanitizer_dtor_callback_vptr",
1804e3b55780SDimitry Andric                                 VTablePtr);
180545b53394SDimitry Andric     }
180645b53394SDimitry Andric  };
1807145449b1SDimitry Andric 
1808145449b1SDimitry Andric  class SanitizeDtorCleanupBuilder {
1809145449b1SDimitry Andric    ASTContext &Context;
1810145449b1SDimitry Andric    EHScopeStack &EHStack;
1811145449b1SDimitry Andric    const CXXDestructorDecl *DD;
1812e3b55780SDimitry Andric    std::optional<unsigned> StartIndex;
1813145449b1SDimitry Andric 
1814145449b1SDimitry Andric  public:
SanitizeDtorCleanupBuilder(ASTContext & Context,EHScopeStack & EHStack,const CXXDestructorDecl * DD)1815145449b1SDimitry Andric    SanitizeDtorCleanupBuilder(ASTContext &Context, EHScopeStack &EHStack,
1816145449b1SDimitry Andric                               const CXXDestructorDecl *DD)
1817e3b55780SDimitry Andric        : Context(Context), EHStack(EHStack), DD(DD), StartIndex(std::nullopt) {}
PushCleanupForField(const FieldDecl * Field)1818145449b1SDimitry Andric    void PushCleanupForField(const FieldDecl *Field) {
1819ac9a064cSDimitry Andric      if (isEmptyFieldForLayout(Context, Field))
1820145449b1SDimitry Andric        return;
1821145449b1SDimitry Andric      unsigned FieldIndex = Field->getFieldIndex();
1822145449b1SDimitry Andric      if (FieldHasTrivialDestructorBody(Context, Field)) {
1823145449b1SDimitry Andric        if (!StartIndex)
1824145449b1SDimitry Andric          StartIndex = FieldIndex;
1825145449b1SDimitry Andric      } else if (StartIndex) {
1826e3b55780SDimitry Andric        EHStack.pushCleanup<SanitizeDtorFieldRange>(NormalAndEHCleanup, DD,
1827e3b55780SDimitry Andric                                                    *StartIndex, FieldIndex);
1828e3b55780SDimitry Andric        StartIndex = std::nullopt;
1829145449b1SDimitry Andric      }
1830145449b1SDimitry Andric    }
End()1831145449b1SDimitry Andric    void End() {
1832145449b1SDimitry Andric      if (StartIndex)
1833145449b1SDimitry Andric        EHStack.pushCleanup<SanitizeDtorFieldRange>(NormalAndEHCleanup, DD,
1834e3b55780SDimitry Andric                                                    *StartIndex, -1);
1835145449b1SDimitry Andric    }
1836145449b1SDimitry Andric  };
183745b53394SDimitry Andric } // end anonymous namespace
183845b53394SDimitry Andric 
183948675466SDimitry Andric /// Emit all code that comes at the end of class's
1840abe15e55SRoman Divacky /// destructor. This is to call destructors on members and base classes
1841abe15e55SRoman Divacky /// in reverse order of their construction.
1842461a67faSDimitry Andric ///
1843461a67faSDimitry Andric /// For a deleting destructor, this also handles the case where a destroying
1844461a67faSDimitry Andric /// operator delete completely overrides the definition.
EnterDtorCleanups(const CXXDestructorDecl * DD,CXXDtorType DtorType)18453d1dcd9bSDimitry Andric void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD,
1846abe15e55SRoman Divacky                                         CXXDtorType DtorType) {
18479f4dbff6SDimitry Andric   assert((!DD->isTrivial() || DD->hasAttr<DLLExportAttr>()) &&
18489f4dbff6SDimitry Andric          "Should not emit dtor epilogue for non-exported trivial dtor!");
1849abe15e55SRoman Divacky 
18503d1dcd9bSDimitry Andric   // The deleting-destructor phase just needs to call the appropriate
18513d1dcd9bSDimitry Andric   // operator delete that Sema picked up.
185279ade4e0SRoman Divacky   if (DtorType == Dtor_Deleting) {
185379ade4e0SRoman Divacky     assert(DD->getOperatorDelete() &&
18549f4dbff6SDimitry Andric            "operator delete missing - EnterDtorCleanups");
1855809500fcSDimitry Andric     if (CXXStructorImplicitParamValue) {
1856809500fcSDimitry Andric       // If there is an implicit param to the deleting dtor, it's a boolean
1857461a67faSDimitry Andric       // telling whether this is a deleting destructor.
1858461a67faSDimitry Andric       if (DD->getOperatorDelete()->isDestroyingOperatorDelete())
1859461a67faSDimitry Andric         EmitConditionalDtorDeleteCall(*this, CXXStructorImplicitParamValue,
1860461a67faSDimitry Andric                                       /*ReturnAfterDelete*/true);
1861461a67faSDimitry Andric       else
1862809500fcSDimitry Andric         EHStack.pushCleanup<CallDtorDeleteConditional>(
1863809500fcSDimitry Andric             NormalAndEHCleanup, CXXStructorImplicitParamValue);
1864809500fcSDimitry Andric     } else {
1865461a67faSDimitry Andric       if (DD->getOperatorDelete()->isDestroyingOperatorDelete()) {
1866461a67faSDimitry Andric         const CXXRecordDecl *ClassDecl = DD->getParent();
1867461a67faSDimitry Andric         EmitDeleteCall(DD->getOperatorDelete(),
1868461a67faSDimitry Andric                        LoadThisForDtorDelete(*this, DD),
1869461a67faSDimitry Andric                        getContext().getTagDeclType(ClassDecl));
1870461a67faSDimitry Andric         EmitBranchThroughCleanup(ReturnBlock);
1871461a67faSDimitry Andric       } else {
18723d1dcd9bSDimitry Andric         EHStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup);
1873809500fcSDimitry Andric       }
1874461a67faSDimitry Andric     }
187579ade4e0SRoman Divacky     return;
187679ade4e0SRoman Divacky   }
187779ade4e0SRoman Divacky 
18783d1dcd9bSDimitry Andric   const CXXRecordDecl *ClassDecl = DD->getParent();
18793d1dcd9bSDimitry Andric 
188036981b17SDimitry Andric   // Unions have no bases and do not call field destructors.
188136981b17SDimitry Andric   if (ClassDecl->isUnion())
188236981b17SDimitry Andric     return;
188336981b17SDimitry Andric 
18843d1dcd9bSDimitry Andric   // The complete-destructor phase just destructs all the virtual bases.
188579ade4e0SRoman Divacky   if (DtorType == Dtor_Complete) {
188645b53394SDimitry Andric     // Poison the vtable pointer such that access after the base
188745b53394SDimitry Andric     // and member destructors are invoked is invalid.
188845b53394SDimitry Andric     if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
188945b53394SDimitry Andric         SanOpts.has(SanitizerKind::Memory) && ClassDecl->getNumVBases() &&
189045b53394SDimitry Andric         ClassDecl->isPolymorphic())
189145b53394SDimitry Andric       EHStack.pushCleanup<SanitizeDtorVTable>(NormalAndEHCleanup, DD);
18923d1dcd9bSDimitry Andric 
18933d1dcd9bSDimitry Andric     // We push them in the forward order so that they'll be popped in
18943d1dcd9bSDimitry Andric     // the reverse order.
18959f4dbff6SDimitry Andric     for (const auto &Base : ClassDecl->vbases()) {
1896519fc96cSDimitry Andric       auto *BaseClassDecl =
1897519fc96cSDimitry Andric           cast<CXXRecordDecl>(Base.getType()->castAs<RecordType>()->getDecl());
189879ade4e0SRoman Divacky 
1899145449b1SDimitry Andric       if (BaseClassDecl->hasTrivialDestructor()) {
1900145449b1SDimitry Andric         // Under SanitizeMemoryUseAfterDtor, poison the trivial base class
1901145449b1SDimitry Andric         // memory. For non-trival base classes the same is done in the class
1902145449b1SDimitry Andric         // destructor.
1903145449b1SDimitry Andric         if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1904145449b1SDimitry Andric             SanOpts.has(SanitizerKind::Memory) && !BaseClassDecl->isEmpty())
1905145449b1SDimitry Andric           EHStack.pushCleanup<SanitizeDtorTrivialBase>(NormalAndEHCleanup,
19063d1dcd9bSDimitry Andric                                                        BaseClassDecl,
19073d1dcd9bSDimitry Andric                                                        /*BaseIsVirtual*/ true);
1908145449b1SDimitry Andric       } else {
1909145449b1SDimitry Andric         EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, BaseClassDecl,
1910145449b1SDimitry Andric                                           /*BaseIsVirtual*/ true);
1911145449b1SDimitry Andric       }
191279ade4e0SRoman Divacky     }
19133d1dcd9bSDimitry Andric 
191479ade4e0SRoman Divacky     return;
191579ade4e0SRoman Divacky   }
191679ade4e0SRoman Divacky 
191779ade4e0SRoman Divacky   assert(DtorType == Dtor_Base);
191845b53394SDimitry Andric   // Poison the vtable pointer if it has no virtual bases, but inherits
191945b53394SDimitry Andric   // virtual functions.
192045b53394SDimitry Andric   if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
192145b53394SDimitry Andric       SanOpts.has(SanitizerKind::Memory) && !ClassDecl->getNumVBases() &&
192245b53394SDimitry Andric       ClassDecl->isPolymorphic())
192345b53394SDimitry Andric     EHStack.pushCleanup<SanitizeDtorVTable>(NormalAndEHCleanup, DD);
192479ade4e0SRoman Divacky 
19253d1dcd9bSDimitry Andric   // Destroy non-virtual bases.
19269f4dbff6SDimitry Andric   for (const auto &Base : ClassDecl->bases()) {
19273d1dcd9bSDimitry Andric     // Ignore virtual bases.
19283d1dcd9bSDimitry Andric     if (Base.isVirtual())
19293d1dcd9bSDimitry Andric       continue;
19303d1dcd9bSDimitry Andric 
19313d1dcd9bSDimitry Andric     CXXRecordDecl *BaseClassDecl = Base.getType()->getAsCXXRecordDecl();
19323d1dcd9bSDimitry Andric 
1933145449b1SDimitry Andric     if (BaseClassDecl->hasTrivialDestructor()) {
1934145449b1SDimitry Andric       if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1935145449b1SDimitry Andric           SanOpts.has(SanitizerKind::Memory) && !BaseClassDecl->isEmpty())
1936145449b1SDimitry Andric         EHStack.pushCleanup<SanitizeDtorTrivialBase>(NormalAndEHCleanup,
19373d1dcd9bSDimitry Andric                                                      BaseClassDecl,
19383d1dcd9bSDimitry Andric                                                      /*BaseIsVirtual*/ false);
1939145449b1SDimitry Andric     } else {
1940145449b1SDimitry Andric       EHStack.pushCleanup<CallBaseDtor>(NormalAndEHCleanup, BaseClassDecl,
1941145449b1SDimitry Andric                                         /*BaseIsVirtual*/ false);
1942145449b1SDimitry Andric     }
19433d1dcd9bSDimitry Andric   }
19443d1dcd9bSDimitry Andric 
194545b53394SDimitry Andric   // Poison fields such that access after their destructors are
194645b53394SDimitry Andric   // invoked, and before the base class destructor runs, is invalid.
1947145449b1SDimitry Andric   bool SanitizeFields = CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1948145449b1SDimitry Andric                         SanOpts.has(SanitizerKind::Memory);
1949145449b1SDimitry Andric   SanitizeDtorCleanupBuilder SanitizeBuilder(getContext(), EHStack, DD);
195045b53394SDimitry Andric 
19513d1dcd9bSDimitry Andric   // Destroy direct fields.
19529f4dbff6SDimitry Andric   for (const auto *Field : ClassDecl->fields()) {
1953145449b1SDimitry Andric     if (SanitizeFields)
1954145449b1SDimitry Andric       SanitizeBuilder.PushCleanupForField(Field);
1955145449b1SDimitry Andric 
19569f4dbff6SDimitry Andric     QualType type = Field->getType();
1957180abc3dSDimitry Andric     QualType::DestructionKind dtorKind = type.isDestructedType();
1958145449b1SDimitry Andric     if (!dtorKind)
1959145449b1SDimitry Andric       continue;
1960abe15e55SRoman Divacky 
1961dbe13110SDimitry Andric     // Anonymous union members do not have their destructors called.
1962dbe13110SDimitry Andric     const RecordType *RT = type->getAsUnionType();
1963145449b1SDimitry Andric     if (RT && RT->getDecl()->isAnonymousStructOrUnion())
1964145449b1SDimitry Andric       continue;
1965dbe13110SDimitry Andric 
1966180abc3dSDimitry Andric     CleanupKind cleanupKind = getCleanupKind(dtorKind);
1967145449b1SDimitry Andric     EHStack.pushCleanup<DestroyField>(
1968145449b1SDimitry Andric         cleanupKind, Field, getDestroyer(dtorKind), cleanupKind & EHCleanup);
1969abe15e55SRoman Divacky   }
1970145449b1SDimitry Andric 
1971145449b1SDimitry Andric   if (SanitizeFields)
1972145449b1SDimitry Andric     SanitizeBuilder.End();
1973abe15e55SRoman Divacky }
1974ee791ddeSRoman Divacky 
1975180abc3dSDimitry Andric /// EmitCXXAggrConstructorCall - Emit a loop to call a particular
1976180abc3dSDimitry Andric /// constructor for each of several members of an array.
19773d1dcd9bSDimitry Andric ///
1978180abc3dSDimitry Andric /// \param ctor the constructor to call for each element
1979180abc3dSDimitry Andric /// \param arrayType the type of the array to initialize
1980180abc3dSDimitry Andric /// \param arrayBegin an arrayType*
1981180abc3dSDimitry Andric /// \param zeroInitialize true if each element should be
1982180abc3dSDimitry Andric ///   zero-initialized before it is constructed
EmitCXXAggrConstructorCall(const CXXConstructorDecl * ctor,const ArrayType * arrayType,Address arrayBegin,const CXXConstructExpr * E,bool NewPointerIsChecked,bool zeroInitialize)198306d4ba38SDimitry Andric void CodeGenFunction::EmitCXXAggrConstructorCall(
19842b6b257fSDimitry Andric     const CXXConstructorDecl *ctor, const ArrayType *arrayType,
1985c7e70c43SDimitry Andric     Address arrayBegin, const CXXConstructExpr *E, bool NewPointerIsChecked,
1986c7e70c43SDimitry Andric     bool zeroInitialize) {
1987180abc3dSDimitry Andric   QualType elementType;
1988180abc3dSDimitry Andric   llvm::Value *numElements =
1989180abc3dSDimitry Andric     emitArrayLength(arrayType, elementType, arrayBegin);
1990ee791ddeSRoman Divacky 
1991c7e70c43SDimitry Andric   EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, E,
1992c7e70c43SDimitry Andric                              NewPointerIsChecked, zeroInitialize);
1993ee791ddeSRoman Divacky }
1994ee791ddeSRoman Divacky 
1995180abc3dSDimitry Andric /// EmitCXXAggrConstructorCall - Emit a loop to call a particular
1996180abc3dSDimitry Andric /// constructor for each of several members of an array.
1997180abc3dSDimitry Andric ///
1998180abc3dSDimitry Andric /// \param ctor the constructor to call for each element
1999180abc3dSDimitry Andric /// \param numElements the number of elements in the array;
2000180abc3dSDimitry Andric ///   may be zero
200145b53394SDimitry Andric /// \param arrayBase a T*, where T is the type constructed by ctor
2002180abc3dSDimitry Andric /// \param zeroInitialize true if each element should be
2003180abc3dSDimitry Andric ///   zero-initialized before it is constructed
EmitCXXAggrConstructorCall(const CXXConstructorDecl * ctor,llvm::Value * numElements,Address arrayBase,const CXXConstructExpr * E,bool NewPointerIsChecked,bool zeroInitialize)200406d4ba38SDimitry Andric void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor,
2005180abc3dSDimitry Andric                                                  llvm::Value *numElements,
200645b53394SDimitry Andric                                                  Address arrayBase,
200706d4ba38SDimitry Andric                                                  const CXXConstructExpr *E,
2008c7e70c43SDimitry Andric                                                  bool NewPointerIsChecked,
2009180abc3dSDimitry Andric                                                  bool zeroInitialize) {
2010180abc3dSDimitry Andric   // It's legal for numElements to be zero.  This can happen both
2011180abc3dSDimitry Andric   // dynamically, because x can be zero in 'new A[x]', and statically,
2012180abc3dSDimitry Andric   // because of GCC extensions that permit zero-length arrays.  There
2013180abc3dSDimitry Andric   // are probably legitimate places where we could assume that this
2014180abc3dSDimitry Andric   // doesn't happen, but it's not clear that it's worth it.
20159f4dbff6SDimitry Andric   llvm::BranchInst *zeroCheckBranch = nullptr;
2016ee791ddeSRoman Divacky 
2017180abc3dSDimitry Andric   // Optimize for a constant count.
2018180abc3dSDimitry Andric   llvm::ConstantInt *constantCount
2019180abc3dSDimitry Andric     = dyn_cast<llvm::ConstantInt>(numElements);
2020180abc3dSDimitry Andric   if (constantCount) {
2021180abc3dSDimitry Andric     // Just skip out if the constant count is zero.
2022180abc3dSDimitry Andric     if (constantCount->isZero()) return;
2023ee791ddeSRoman Divacky 
2024180abc3dSDimitry Andric   // Otherwise, emit the check.
2025180abc3dSDimitry Andric   } else {
2026180abc3dSDimitry Andric     llvm::BasicBlock *loopBB = createBasicBlock("new.ctorloop");
2027180abc3dSDimitry Andric     llvm::Value *iszero = Builder.CreateIsNull(numElements, "isempty");
2028180abc3dSDimitry Andric     zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB);
2029180abc3dSDimitry Andric     EmitBlock(loopBB);
2030180abc3dSDimitry Andric   }
2031ee791ddeSRoman Divacky 
2032180abc3dSDimitry Andric   // Find the end of the array.
2033344a3780SDimitry Andric   llvm::Type *elementType = arrayBase.getElementType();
2034ac9a064cSDimitry Andric   llvm::Value *arrayBegin = arrayBase.emitRawPointer(*this);
2035344a3780SDimitry Andric   llvm::Value *arrayEnd = Builder.CreateInBoundsGEP(
2036344a3780SDimitry Andric       elementType, arrayBegin, numElements, "arrayctor.end");
2037ee791ddeSRoman Divacky 
2038180abc3dSDimitry Andric   // Enter the loop, setting up a phi for the current location to initialize.
2039180abc3dSDimitry Andric   llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
2040180abc3dSDimitry Andric   llvm::BasicBlock *loopBB = createBasicBlock("arrayctor.loop");
2041180abc3dSDimitry Andric   EmitBlock(loopBB);
2042180abc3dSDimitry Andric   llvm::PHINode *cur = Builder.CreatePHI(arrayBegin->getType(), 2,
2043180abc3dSDimitry Andric                                          "arrayctor.cur");
2044180abc3dSDimitry Andric   cur->addIncoming(arrayBegin, entryBB);
2045ee791ddeSRoman Divacky 
2046ee791ddeSRoman Divacky   // Inside the loop body, emit the constructor call on the array element.
2047180abc3dSDimitry Andric 
204845b53394SDimitry Andric   // The alignment of the base, adjusted by the size of a single element,
204945b53394SDimitry Andric   // provides a conservative estimate of the alignment of every element.
205045b53394SDimitry Andric   // (This assumes we never start tracking offsetted alignments.)
205145b53394SDimitry Andric   //
205245b53394SDimitry Andric   // Note that these are complete objects and so we don't need to
205345b53394SDimitry Andric   // use the non-virtual size or alignment.
2054180abc3dSDimitry Andric   QualType type = getContext().getTypeDeclType(ctor->getParent());
205545b53394SDimitry Andric   CharUnits eltAlignment =
205645b53394SDimitry Andric     arrayBase.getAlignment()
205745b53394SDimitry Andric              .alignmentOfArrayElement(getContext().getTypeSizeInChars(type));
20586f8fc217SDimitry Andric   Address curAddr = Address(cur, elementType, eltAlignment);
2059ee791ddeSRoman Divacky 
20603d1dcd9bSDimitry Andric   // Zero initialize the storage, if requested.
2061180abc3dSDimitry Andric   if (zeroInitialize)
206245b53394SDimitry Andric     EmitNullInitialization(curAddr, type);
20633d1dcd9bSDimitry Andric 
2064ee791ddeSRoman Divacky   // C++ [class.temporary]p4:
2065ee791ddeSRoman Divacky   // There are two contexts in which temporaries are destroyed at a different
2066ee791ddeSRoman Divacky   // point than the end of the full-expression. The first context is when a
2067ee791ddeSRoman Divacky   // default constructor is called to initialize an element of an array.
2068ee791ddeSRoman Divacky   // If the constructor has one or more default arguments, the destruction of
2069ee791ddeSRoman Divacky   // every temporary created in a default argument expression is sequenced
2070ee791ddeSRoman Divacky   // before the construction of the next array element, if any.
2071ee791ddeSRoman Divacky 
207211d2b2d2SRoman Divacky   {
20734ba67500SRoman Divacky     RunCleanupsScope Scope(*this);
2074ee791ddeSRoman Divacky 
2075180abc3dSDimitry Andric     // Evaluate the constructor and its arguments in a regular
2076180abc3dSDimitry Andric     // partial-destroy cleanup.
2077dbe13110SDimitry Andric     if (getLangOpts().Exceptions &&
2078180abc3dSDimitry Andric         !ctor->getParent()->hasTrivialDestructor()) {
2079180abc3dSDimitry Andric       Destroyer *destroyer = destroyCXXObject;
208045b53394SDimitry Andric       pushRegularPartialArrayCleanup(arrayBegin, cur, type, eltAlignment,
208145b53394SDimitry Andric                                      *destroyer);
208211d2b2d2SRoman Divacky     }
208322989816SDimitry Andric     auto currAVS = AggValueSlot::forAddr(
208422989816SDimitry Andric         curAddr, type.getQualifiers(), AggValueSlot::IsDestructed,
208522989816SDimitry Andric         AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased,
208622989816SDimitry Andric         AggValueSlot::DoesNotOverlap, AggValueSlot::IsNotZeroed,
208722989816SDimitry Andric         NewPointerIsChecked ? AggValueSlot::IsSanitizerChecked
208822989816SDimitry Andric                             : AggValueSlot::IsNotSanitizerChecked);
2089180abc3dSDimitry Andric     EmitCXXConstructorCall(ctor, Ctor_Complete, /*ForVirtualBase=*/false,
209022989816SDimitry Andric                            /*Delegating=*/false, currAVS, E);
2091ee791ddeSRoman Divacky   }
2092ee791ddeSRoman Divacky 
2093180abc3dSDimitry Andric   // Go to the next element.
2094344a3780SDimitry Andric   llvm::Value *next = Builder.CreateInBoundsGEP(
2095344a3780SDimitry Andric       elementType, cur, llvm::ConstantInt::get(SizeTy, 1), "arrayctor.next");
2096180abc3dSDimitry Andric   cur->addIncoming(next, Builder.GetInsertBlock());
2097ee791ddeSRoman Divacky 
2098180abc3dSDimitry Andric   // Check whether that's the end of the loop.
2099180abc3dSDimitry Andric   llvm::Value *done = Builder.CreateICmpEQ(next, arrayEnd, "arrayctor.done");
2100180abc3dSDimitry Andric   llvm::BasicBlock *contBB = createBasicBlock("arrayctor.cont");
2101180abc3dSDimitry Andric   Builder.CreateCondBr(done, contBB, loopBB);
2102180abc3dSDimitry Andric 
2103180abc3dSDimitry Andric   // Patch the earlier check to skip over the loop.
2104180abc3dSDimitry Andric   if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB);
2105180abc3dSDimitry Andric 
2106180abc3dSDimitry Andric   EmitBlock(contBB);
2107ee791ddeSRoman Divacky }
2108ee791ddeSRoman Divacky 
destroyCXXObject(CodeGenFunction & CGF,Address addr,QualType type)2109180abc3dSDimitry Andric void CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF,
211045b53394SDimitry Andric                                        Address addr,
2111180abc3dSDimitry Andric                                        QualType type) {
2112180abc3dSDimitry Andric   const RecordType *rtype = type->castAs<RecordType>();
2113180abc3dSDimitry Andric   const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl());
2114180abc3dSDimitry Andric   const CXXDestructorDecl *dtor = record->getDestructor();
2115180abc3dSDimitry Andric   assert(!dtor->isTrivial());
2116180abc3dSDimitry Andric   CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false,
211722989816SDimitry Andric                             /*Delegating=*/false, addr, type);
2118ee791ddeSRoman Divacky }
2119ee791ddeSRoman Divacky 
EmitCXXConstructorCall(const CXXConstructorDecl * D,CXXCtorType Type,bool ForVirtualBase,bool Delegating,AggValueSlot ThisAVS,const CXXConstructExpr * E)212006d4ba38SDimitry Andric void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
212106d4ba38SDimitry Andric                                              CXXCtorType Type,
212206d4ba38SDimitry Andric                                              bool ForVirtualBase,
212322989816SDimitry Andric                                              bool Delegating,
212422989816SDimitry Andric                                              AggValueSlot ThisAVS,
212522989816SDimitry Andric                                              const CXXConstructExpr *E) {
21262b6b257fSDimitry Andric   CallArgList Args;
212722989816SDimitry Andric   Address This = ThisAVS.getAddress();
212822989816SDimitry Andric   LangAS SlotAS = ThisAVS.getQualifiers().getAddressSpace();
2129b1c73532SDimitry Andric   LangAS ThisAS = D->getFunctionObjectParameterType().getAddressSpace();
2130ac9a064cSDimitry Andric   llvm::Value *ThisPtr =
2131ac9a064cSDimitry Andric       getAsNaturalPointerTo(This, D->getThisType()->getPointeeType());
213222989816SDimitry Andric 
2133676fbe81SDimitry Andric   if (SlotAS != ThisAS) {
2134676fbe81SDimitry Andric     unsigned TargetThisAS = getContext().getTargetAddressSpace(ThisAS);
21357fa27ce4SDimitry Andric     llvm::Type *NewType =
21367fa27ce4SDimitry Andric         llvm::PointerType::get(getLLVMContext(), TargetThisAS);
2137ac9a064cSDimitry Andric     ThisPtr = getTargetHooks().performAddrSpaceCast(*this, ThisPtr, ThisAS,
2138ac9a064cSDimitry Andric                                                     SlotAS, NewType);
2139676fbe81SDimitry Andric   }
214022989816SDimitry Andric 
21412b6b257fSDimitry Andric   // Push the this ptr.
2142676fbe81SDimitry Andric   Args.add(RValue::get(ThisPtr), D->getThisType());
21432b6b257fSDimitry Andric 
21442b6b257fSDimitry Andric   // If this is a trivial constructor, emit a memcpy now before we lose
21452b6b257fSDimitry Andric   // the alignment information on the argument.
21462b6b257fSDimitry Andric   // FIXME: It would be better to preserve alignment information into CallArg.
21472b6b257fSDimitry Andric   if (isMemcpyEquivalentSpecialMember(D)) {
21482b6b257fSDimitry Andric     assert(E->getNumArgs() == 1 && "unexpected argcount for trivial ctor");
21492b6b257fSDimitry Andric 
21502b6b257fSDimitry Andric     const Expr *Arg = E->getArg(0);
215148675466SDimitry Andric     LValue Src = EmitLValue(Arg);
21522b6b257fSDimitry Andric     QualType DestTy = getContext().getTypeDeclType(D->getParent());
215348675466SDimitry Andric     LValue Dest = MakeAddrLValue(This, DestTy);
215422989816SDimitry Andric     EmitAggregateCopyCtor(Dest, Src, ThisAVS.mayOverlap());
21552b6b257fSDimitry Andric     return;
21562b6b257fSDimitry Andric   }
21572b6b257fSDimitry Andric 
21582b6b257fSDimitry Andric   // Add the rest of the user-supplied arguments.
21592b6b257fSDimitry Andric   const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
21607442d6faSDimitry Andric   EvaluationOrder Order = E->isListInitialization()
21617442d6faSDimitry Andric                               ? EvaluationOrder::ForceLeftToRight
21627442d6faSDimitry Andric                               : EvaluationOrder::Default;
21637442d6faSDimitry Andric   EmitCallArgs(Args, FPT, E->arguments(), E->getConstructor(),
21647442d6faSDimitry Andric                /*ParamsToSkip*/ 0, Order);
21652b6b257fSDimitry Andric 
216648675466SDimitry Andric   EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args,
216722989816SDimitry Andric                          ThisAVS.mayOverlap(), E->getExprLoc(),
216822989816SDimitry Andric                          ThisAVS.isSanitizerChecked());
21692b6b257fSDimitry Andric }
21702b6b257fSDimitry Andric 
canEmitDelegateCallArgs(CodeGenFunction & CGF,const CXXConstructorDecl * Ctor,CXXCtorType Type,CallArgList & Args)21712b6b257fSDimitry Andric static bool canEmitDelegateCallArgs(CodeGenFunction &CGF,
21722b6b257fSDimitry Andric                                     const CXXConstructorDecl *Ctor,
21732b6b257fSDimitry Andric                                     CXXCtorType Type, CallArgList &Args) {
21742b6b257fSDimitry Andric   // We can't forward a variadic call.
21752b6b257fSDimitry Andric   if (Ctor->isVariadic())
21762b6b257fSDimitry Andric     return false;
21772b6b257fSDimitry Andric 
21782b6b257fSDimitry Andric   if (CGF.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
21792b6b257fSDimitry Andric     // If the parameters are callee-cleanup, it's not safe to forward.
21802b6b257fSDimitry Andric     for (auto *P : Ctor->parameters())
2181519fc96cSDimitry Andric       if (P->needsDestruction(CGF.getContext()))
21822b6b257fSDimitry Andric         return false;
21832b6b257fSDimitry Andric 
21842b6b257fSDimitry Andric     // Likewise if they're inalloca.
21852b6b257fSDimitry Andric     const CGFunctionInfo &Info =
21867442d6faSDimitry Andric         CGF.CGM.getTypes().arrangeCXXConstructorCall(Args, Ctor, Type, 0, 0);
21872b6b257fSDimitry Andric     if (Info.usesInAlloca())
21882b6b257fSDimitry Andric       return false;
21892b6b257fSDimitry Andric   }
21902b6b257fSDimitry Andric 
21912b6b257fSDimitry Andric   // Anything else should be OK.
21922b6b257fSDimitry Andric   return true;
21932b6b257fSDimitry Andric }
21942b6b257fSDimitry Andric 
EmitCXXConstructorCall(const CXXConstructorDecl * D,CXXCtorType Type,bool ForVirtualBase,bool Delegating,Address This,CallArgList & Args,AggValueSlot::Overlap_t Overlap,SourceLocation Loc,bool NewPointerIsChecked)21952b6b257fSDimitry Andric void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
21962b6b257fSDimitry Andric                                              CXXCtorType Type,
21972b6b257fSDimitry Andric                                              bool ForVirtualBase,
21982b6b257fSDimitry Andric                                              bool Delegating,
21992b6b257fSDimitry Andric                                              Address This,
220048675466SDimitry Andric                                              CallArgList &Args,
220148675466SDimitry Andric                                              AggValueSlot::Overlap_t Overlap,
2202c7e70c43SDimitry Andric                                              SourceLocation Loc,
2203c7e70c43SDimitry Andric                                              bool NewPointerIsChecked) {
220445b53394SDimitry Andric   const CXXRecordDecl *ClassDecl = D->getParent();
220545b53394SDimitry Andric 
2206c7e70c43SDimitry Andric   if (!NewPointerIsChecked)
2207ac9a064cSDimitry Andric     EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, Loc, This,
2208c7e70c43SDimitry Andric                   getContext().getRecordType(ClassDecl), CharUnits::Zero());
22099f4dbff6SDimitry Andric 
22105e20cdd8SDimitry Andric   if (D->isTrivial() && D->isDefaultConstructor()) {
22112b6b257fSDimitry Andric     assert(Args.size() == 1 && "trivial default ctor with args");
22125e20cdd8SDimitry Andric     return;
22135e20cdd8SDimitry Andric   }
22145e20cdd8SDimitry Andric 
22155e20cdd8SDimitry Andric   // If this is a trivial constructor, just emit what's needed. If this is a
22165e20cdd8SDimitry Andric   // union copy constructor, we must emit a memcpy, because the AST does not
22175e20cdd8SDimitry Andric   // model that copy.
22185e20cdd8SDimitry Andric   if (isMemcpyEquivalentSpecialMember(D)) {
22192b6b257fSDimitry Andric     assert(Args.size() == 2 && "unexpected argcount for trivial ctor");
22202b6b257fSDimitry Andric     QualType SrcTy = D->getParamDecl(0)->getType().getNonReferenceType();
2221ac9a064cSDimitry Andric     Address Src = makeNaturalAddressForPointer(
2222ac9a064cSDimitry Andric         Args[1].getRValue(*this).getScalarVal(), SrcTy);
222348675466SDimitry Andric     LValue SrcLVal = MakeAddrLValue(Src, SrcTy);
222445b53394SDimitry Andric     QualType DestTy = getContext().getTypeDeclType(ClassDecl);
222548675466SDimitry Andric     LValue DestLVal = MakeAddrLValue(This, DestTy);
222648675466SDimitry Andric     EmitAggregateCopyCtor(DestLVal, SrcLVal, Overlap);
22275e20cdd8SDimitry Andric     return;
22285e20cdd8SDimitry Andric   }
22295e20cdd8SDimitry Andric 
22307442d6faSDimitry Andric   bool PassPrototypeArgs = true;
22312b6b257fSDimitry Andric   // Check whether we can actually emit the constructor before trying to do so.
22322b6b257fSDimitry Andric   if (auto Inherited = D->getInheritedConstructor()) {
22337442d6faSDimitry Andric     PassPrototypeArgs = getTypes().inheritingCtorHasParams(Inherited, Type);
22347442d6faSDimitry Andric     if (PassPrototypeArgs && !canEmitDelegateCallArgs(*this, D, Type, Args)) {
22352b6b257fSDimitry Andric       EmitInlinedInheritingCXXConstructorCall(D, Type, ForVirtualBase,
22362b6b257fSDimitry Andric                                               Delegating, Args);
22372b6b257fSDimitry Andric       return;
22382b6b257fSDimitry Andric     }
22392b6b257fSDimitry Andric   }
22409f4dbff6SDimitry Andric 
22419f4dbff6SDimitry Andric   // Insert any ABI-specific implicit constructor arguments.
2242cfca06d7SDimitry Andric   CGCXXABI::AddedStructorArgCounts ExtraArgs =
22437442d6faSDimitry Andric       CGM.getCXXABI().addImplicitConstructorArgs(*this, D, Type, ForVirtualBase,
22447442d6faSDimitry Andric                                                  Delegating, Args);
22459f4dbff6SDimitry Andric 
22469f4dbff6SDimitry Andric   // Emit the call.
224722989816SDimitry Andric   llvm::Constant *CalleePtr = CGM.getAddrOfCXXStructor(GlobalDecl(D, Type));
22487442d6faSDimitry Andric   const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall(
22497442d6faSDimitry Andric       Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs);
2250676fbe81SDimitry Andric   CGCallee Callee = CGCallee::forDirect(CalleePtr, GlobalDecl(D, Type));
2251344a3780SDimitry Andric   EmitCall(Info, Callee, ReturnValueSlot(), Args, nullptr, false, Loc);
225245b53394SDimitry Andric 
225345b53394SDimitry Andric   // Generate vtable assumptions if we're constructing a complete object
225445b53394SDimitry Andric   // with a vtable.  We don't do this for base subobjects for two reasons:
225545b53394SDimitry Andric   // first, it's incorrect for classes with virtual bases, and second, we're
225645b53394SDimitry Andric   // about to overwrite the vptrs anyway.
225745b53394SDimitry Andric   // We also have to make sure if we can refer to vtable:
225845b53394SDimitry Andric   // - Otherwise we can refer to vtable if it's safe to speculatively emit.
225945b53394SDimitry Andric   // FIXME: If vtable is used by ctor/dtor, or if vtable is external and we are
226045b53394SDimitry Andric   // sure that definition of vtable is not hidden,
226145b53394SDimitry Andric   // then we are always safe to refer to it.
226245b53394SDimitry Andric   // FIXME: It looks like InstCombine is very inefficient on dealing with
226345b53394SDimitry Andric   // assumes. Make assumption loads require -fstrict-vtable-pointers temporarily.
226445b53394SDimitry Andric   if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
226545b53394SDimitry Andric       ClassDecl->isDynamicClass() && Type != Ctor_Base &&
226645b53394SDimitry Andric       CGM.getCXXABI().canSpeculativelyEmitVTable(ClassDecl) &&
226745b53394SDimitry Andric       CGM.getCodeGenOpts().StrictVTablePointers)
226845b53394SDimitry Andric     EmitVTableAssumptionLoads(ClassDecl, This);
226945b53394SDimitry Andric }
227045b53394SDimitry Andric 
EmitInheritedCXXConstructorCall(const CXXConstructorDecl * D,bool ForVirtualBase,Address This,bool InheritedFromVBase,const CXXInheritedCtorInitExpr * E)22712b6b257fSDimitry Andric void CodeGenFunction::EmitInheritedCXXConstructorCall(
22722b6b257fSDimitry Andric     const CXXConstructorDecl *D, bool ForVirtualBase, Address This,
22732b6b257fSDimitry Andric     bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E) {
22742b6b257fSDimitry Andric   CallArgList Args;
2275ac9a064cSDimitry Andric   CallArg ThisArg(RValue::get(getAsNaturalPointerTo(
2276ac9a064cSDimitry Andric                       This, D->getThisType()->getPointeeType())),
2277ac9a064cSDimitry Andric                   D->getThisType());
22782b6b257fSDimitry Andric 
22792b6b257fSDimitry Andric   // Forward the parameters.
22802b6b257fSDimitry Andric   if (InheritedFromVBase &&
22812b6b257fSDimitry Andric       CGM.getTarget().getCXXABI().hasConstructorVariants()) {
22822b6b257fSDimitry Andric     // Nothing to do; this construction is not responsible for constructing
22832b6b257fSDimitry Andric     // the base class containing the inherited constructor.
22842b6b257fSDimitry Andric     // FIXME: Can we just pass undef's for the remaining arguments if we don't
22852b6b257fSDimitry Andric     // have constructor variants?
22862b6b257fSDimitry Andric     Args.push_back(ThisArg);
22872b6b257fSDimitry Andric   } else if (!CXXInheritedCtorInitExprArgs.empty()) {
22882b6b257fSDimitry Andric     // The inheriting constructor was inlined; just inject its arguments.
22892b6b257fSDimitry Andric     assert(CXXInheritedCtorInitExprArgs.size() >= D->getNumParams() &&
22902b6b257fSDimitry Andric            "wrong number of parameters for inherited constructor call");
22912b6b257fSDimitry Andric     Args = CXXInheritedCtorInitExprArgs;
22922b6b257fSDimitry Andric     Args[0] = ThisArg;
22932b6b257fSDimitry Andric   } else {
22942b6b257fSDimitry Andric     // The inheriting constructor was not inlined. Emit delegating arguments.
22952b6b257fSDimitry Andric     Args.push_back(ThisArg);
22962b6b257fSDimitry Andric     const auto *OuterCtor = cast<CXXConstructorDecl>(CurCodeDecl);
22972b6b257fSDimitry Andric     assert(OuterCtor->getNumParams() == D->getNumParams());
22982b6b257fSDimitry Andric     assert(!OuterCtor->isVariadic() && "should have been inlined");
22992b6b257fSDimitry Andric 
23002b6b257fSDimitry Andric     for (const auto *Param : OuterCtor->parameters()) {
23012b6b257fSDimitry Andric       assert(getContext().hasSameUnqualifiedType(
23022b6b257fSDimitry Andric           OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->getType(),
23032b6b257fSDimitry Andric           Param->getType()));
23042b6b257fSDimitry Andric       EmitDelegateCallArg(Args, Param, E->getLocation());
23052b6b257fSDimitry Andric 
23062b6b257fSDimitry Andric       // Forward __attribute__(pass_object_size).
23072b6b257fSDimitry Andric       if (Param->hasAttr<PassObjectSizeAttr>()) {
23082b6b257fSDimitry Andric         auto *POSParam = SizeArguments[Param];
23092b6b257fSDimitry Andric         assert(POSParam && "missing pass_object_size value for forwarding");
23102b6b257fSDimitry Andric         EmitDelegateCallArg(Args, POSParam, E->getLocation());
23112b6b257fSDimitry Andric       }
23122b6b257fSDimitry Andric     }
23132b6b257fSDimitry Andric   }
23142b6b257fSDimitry Andric 
23152b6b257fSDimitry Andric   EmitCXXConstructorCall(D, Ctor_Base, ForVirtualBase, /*Delegating*/false,
231648675466SDimitry Andric                          This, Args, AggValueSlot::MayOverlap,
2317c7e70c43SDimitry Andric                          E->getLocation(), /*NewPointerIsChecked*/true);
23182b6b257fSDimitry Andric }
23192b6b257fSDimitry Andric 
EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl * Ctor,CXXCtorType CtorType,bool ForVirtualBase,bool Delegating,CallArgList & Args)23202b6b257fSDimitry Andric void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall(
23212b6b257fSDimitry Andric     const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase,
23222b6b257fSDimitry Andric     bool Delegating, CallArgList &Args) {
23237442d6faSDimitry Andric   GlobalDecl GD(Ctor, CtorType);
23247442d6faSDimitry Andric   InlinedInheritingConstructorScope Scope(*this, GD);
23257442d6faSDimitry Andric   ApplyInlineDebugLocation DebugScope(*this, GD);
2326676fbe81SDimitry Andric   RunCleanupsScope RunCleanups(*this);
23272b6b257fSDimitry Andric 
23282b6b257fSDimitry Andric   // Save the arguments to be passed to the inherited constructor.
23292b6b257fSDimitry Andric   CXXInheritedCtorInitExprArgs = Args;
23302b6b257fSDimitry Andric 
23312b6b257fSDimitry Andric   FunctionArgList Params;
23322b6b257fSDimitry Andric   QualType RetType = BuildFunctionArgList(CurGD, Params);
23332b6b257fSDimitry Andric   FnRetTy = RetType;
23342b6b257fSDimitry Andric 
23352b6b257fSDimitry Andric   // Insert any ABI-specific implicit constructor arguments.
23362b6b257fSDimitry Andric   CGM.getCXXABI().addImplicitConstructorArgs(*this, Ctor, CtorType,
23372b6b257fSDimitry Andric                                              ForVirtualBase, Delegating, Args);
23382b6b257fSDimitry Andric 
23392b6b257fSDimitry Andric   // Emit a simplified prolog. We only need to emit the implicit params.
23402b6b257fSDimitry Andric   assert(Args.size() >= Params.size() && "too few arguments for call");
23412b6b257fSDimitry Andric   for (unsigned I = 0, N = Args.size(); I != N; ++I) {
23422b6b257fSDimitry Andric     if (I < Params.size() && isa<ImplicitParamDecl>(Params[I])) {
234348675466SDimitry Andric       const RValue &RV = Args[I].getRValue(*this);
23442b6b257fSDimitry Andric       assert(!RV.isComplex() && "complex indirect params not supported");
23452b6b257fSDimitry Andric       ParamValue Val = RV.isScalar()
23462b6b257fSDimitry Andric                            ? ParamValue::forDirect(RV.getScalarVal())
23472b6b257fSDimitry Andric                            : ParamValue::forIndirect(RV.getAggregateAddress());
23482b6b257fSDimitry Andric       EmitParmDecl(*Params[I], Val, I + 1);
23492b6b257fSDimitry Andric     }
23502b6b257fSDimitry Andric   }
23512b6b257fSDimitry Andric 
23522b6b257fSDimitry Andric   // Create a return value slot if the ABI implementation wants one.
23532b6b257fSDimitry Andric   // FIXME: This is dumb, we should ask the ABI not to try to set the return
23542b6b257fSDimitry Andric   // value instead.
23552b6b257fSDimitry Andric   if (!RetType->isVoidType())
23562b6b257fSDimitry Andric     ReturnValue = CreateIRTemp(RetType, "retval.inhctor");
23572b6b257fSDimitry Andric 
23582b6b257fSDimitry Andric   CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
23592b6b257fSDimitry Andric   CXXThisValue = CXXABIThisValue;
23602b6b257fSDimitry Andric 
23612b6b257fSDimitry Andric   // Directly emit the constructor initializers.
23622b6b257fSDimitry Andric   EmitCtorPrologue(Ctor, CtorType, Params);
23632b6b257fSDimitry Andric }
23642b6b257fSDimitry Andric 
EmitVTableAssumptionLoad(const VPtr & Vptr,Address This)236545b53394SDimitry Andric void CodeGenFunction::EmitVTableAssumptionLoad(const VPtr &Vptr, Address This) {
236645b53394SDimitry Andric   llvm::Value *VTableGlobal =
236745b53394SDimitry Andric       CGM.getCXXABI().getVTableAddressPoint(Vptr.Base, Vptr.VTableClass);
236845b53394SDimitry Andric   if (!VTableGlobal)
236945b53394SDimitry Andric     return;
237045b53394SDimitry Andric 
237145b53394SDimitry Andric   // We can just use the base offset in the complete class.
237245b53394SDimitry Andric   CharUnits NonVirtualOffset = Vptr.Base.getBaseOffset();
237345b53394SDimitry Andric 
237445b53394SDimitry Andric   if (!NonVirtualOffset.isZero())
237545b53394SDimitry Andric     This =
237645b53394SDimitry Andric         ApplyNonVirtualAndVirtualOffset(*this, This, NonVirtualOffset, nullptr,
237745b53394SDimitry Andric                                         Vptr.VTableClass, Vptr.NearestVBase);
237845b53394SDimitry Andric 
237945b53394SDimitry Andric   llvm::Value *VPtrValue =
238045b53394SDimitry Andric       GetVTablePtr(This, VTableGlobal->getType(), Vptr.VTableClass);
238145b53394SDimitry Andric   llvm::Value *Cmp =
238245b53394SDimitry Andric       Builder.CreateICmpEQ(VPtrValue, VTableGlobal, "cmp.vtables");
238345b53394SDimitry Andric   Builder.CreateAssumption(Cmp);
238445b53394SDimitry Andric }
238545b53394SDimitry Andric 
EmitVTableAssumptionLoads(const CXXRecordDecl * ClassDecl,Address This)238645b53394SDimitry Andric void CodeGenFunction::EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl,
238745b53394SDimitry Andric                                                 Address This) {
238845b53394SDimitry Andric   if (CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl))
238945b53394SDimitry Andric     for (const VPtr &Vptr : getVTablePointers(ClassDecl))
239045b53394SDimitry Andric       EmitVTableAssumptionLoad(Vptr, This);
2391ee791ddeSRoman Divacky }
2392ee791ddeSRoman Divacky 
239379ade4e0SRoman Divacky void
EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl * D,Address This,Address Src,const CXXConstructExpr * E)2394bca07a45SDimitry Andric CodeGenFunction::EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D,
239545b53394SDimitry Andric                                                 Address This, Address Src,
239606d4ba38SDimitry Andric                                                 const CXXConstructExpr *E) {
23979f4dbff6SDimitry Andric   const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
2398bca07a45SDimitry Andric 
2399bca07a45SDimitry Andric   CallArgList Args;
2400bca07a45SDimitry Andric 
2401bca07a45SDimitry Andric   // Push the this ptr.
2402ac9a064cSDimitry Andric   Args.add(RValue::get(getAsNaturalPointerTo(This, D->getThisType())),
2403ac9a064cSDimitry Andric            D->getThisType());
2404bca07a45SDimitry Andric 
2405bca07a45SDimitry Andric   // Push the src ptr.
24069f4dbff6SDimitry Andric   QualType QT = *(FPT->param_type_begin());
240736981b17SDimitry Andric   llvm::Type *t = CGM.getTypes().ConvertType(QT);
2408ac9a064cSDimitry Andric   llvm::Value *Val = getAsNaturalPointerTo(Src, D->getThisType());
2409ac9a064cSDimitry Andric   llvm::Value *SrcVal = Builder.CreateBitCast(Val, t);
2410145449b1SDimitry Andric   Args.add(RValue::get(SrcVal), QT);
2411bca07a45SDimitry Andric 
2412bca07a45SDimitry Andric   // Skip over first argument (Src).
241345b53394SDimitry Andric   EmitCallArgs(Args, FPT, drop_begin(E->arguments(), 1), E->getConstructor(),
241406d4ba38SDimitry Andric                /*ParamsToSkip*/ 1);
2415bca07a45SDimitry Andric 
2416c7e70c43SDimitry Andric   EmitCXXConstructorCall(D, Ctor_Complete, /*ForVirtualBase*/false,
2417c7e70c43SDimitry Andric                          /*Delegating*/false, This, Args,
2418c7e70c43SDimitry Andric                          AggValueSlot::MayOverlap, E->getExprLoc(),
2419c7e70c43SDimitry Andric                          /*NewPointerIsChecked*/false);
2420bca07a45SDimitry Andric }
2421bca07a45SDimitry Andric 
2422bca07a45SDimitry Andric void
EmitDelegateCXXConstructorCall(const CXXConstructorDecl * Ctor,CXXCtorType CtorType,const FunctionArgList & Args,SourceLocation Loc)242379ade4e0SRoman Divacky CodeGenFunction::EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor,
242479ade4e0SRoman Divacky                                                 CXXCtorType CtorType,
2425bfef3995SDimitry Andric                                                 const FunctionArgList &Args,
2426bfef3995SDimitry Andric                                                 SourceLocation Loc) {
242779ade4e0SRoman Divacky   CallArgList DelegateArgs;
242879ade4e0SRoman Divacky 
242979ade4e0SRoman Divacky   FunctionArgList::const_iterator I = Args.begin(), E = Args.end();
243079ade4e0SRoman Divacky   assert(I != E && "no parameters to constructor");
243179ade4e0SRoman Divacky 
243279ade4e0SRoman Divacky   // this
24332b6b257fSDimitry Andric   Address This = LoadCXXThisAddress();
2434ac9a064cSDimitry Andric   DelegateArgs.add(RValue::get(getAsNaturalPointerTo(
2435ac9a064cSDimitry Andric                        This, (*I)->getType()->getPointeeType())),
2436ac9a064cSDimitry Andric                    (*I)->getType());
243779ade4e0SRoman Divacky   ++I;
243879ade4e0SRoman Divacky 
24392b6b257fSDimitry Andric   // FIXME: The location of the VTT parameter in the parameter list is
24402b6b257fSDimitry Andric   // specific to the Itanium ABI and shouldn't be hardcoded here.
2441bfef3995SDimitry Andric   if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {
244279ade4e0SRoman Divacky     assert(I != E && "cannot skip vtt parameter, already done with args");
24432b6b257fSDimitry Andric     assert((*I)->getType()->isPointerType() &&
24442b6b257fSDimitry Andric            "skipping parameter not of vtt type");
244579ade4e0SRoman Divacky     ++I;
244679ade4e0SRoman Divacky   }
244779ade4e0SRoman Divacky 
244879ade4e0SRoman Divacky   // Explicit arguments.
244979ade4e0SRoman Divacky   for (; I != E; ++I) {
245001af97d3SDimitry Andric     const VarDecl *param = *I;
2451bfef3995SDimitry Andric     // FIXME: per-argument source location
2452bfef3995SDimitry Andric     EmitDelegateCallArg(DelegateArgs, param, Loc);
245379ade4e0SRoman Divacky   }
245479ade4e0SRoman Divacky 
24552b6b257fSDimitry Andric   EmitCXXConstructorCall(Ctor, CtorType, /*ForVirtualBase=*/false,
245648675466SDimitry Andric                          /*Delegating=*/true, This, DelegateArgs,
2457c7e70c43SDimitry Andric                          AggValueSlot::MayOverlap, Loc,
2458c7e70c43SDimitry Andric                          /*NewPointerIsChecked=*/true);
245979ade4e0SRoman Divacky }
246079ade4e0SRoman Divacky 
246129cafa66SDimitry Andric namespace {
246245b53394SDimitry Andric   struct CallDelegatingCtorDtor final : EHScopeStack::Cleanup {
246329cafa66SDimitry Andric     const CXXDestructorDecl *Dtor;
246445b53394SDimitry Andric     Address Addr;
246529cafa66SDimitry Andric     CXXDtorType Type;
246629cafa66SDimitry Andric 
CallDelegatingCtorDtor__anonf1d54d130511::CallDelegatingCtorDtor246745b53394SDimitry Andric     CallDelegatingCtorDtor(const CXXDestructorDecl *D, Address Addr,
246829cafa66SDimitry Andric                            CXXDtorType Type)
246929cafa66SDimitry Andric       : Dtor(D), Addr(Addr), Type(Type) {}
247029cafa66SDimitry Andric 
Emit__anonf1d54d130511::CallDelegatingCtorDtor24719f4dbff6SDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
247222989816SDimitry Andric       // We are calling the destructor from within the constructor.
247322989816SDimitry Andric       // Therefore, "this" should have the expected type.
2474b1c73532SDimitry Andric       QualType ThisTy = Dtor->getFunctionObjectParameterType();
247529cafa66SDimitry Andric       CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false,
247622989816SDimitry Andric                                 /*Delegating=*/true, Addr, ThisTy);
247729cafa66SDimitry Andric     }
247829cafa66SDimitry Andric   };
247945b53394SDimitry Andric } // end anonymous namespace
248029cafa66SDimitry Andric 
248101af97d3SDimitry Andric void
EmitDelegatingCXXConstructorCall(const CXXConstructorDecl * Ctor,const FunctionArgList & Args)248201af97d3SDimitry Andric CodeGenFunction::EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor,
248301af97d3SDimitry Andric                                                   const FunctionArgList &Args) {
248401af97d3SDimitry Andric   assert(Ctor->isDelegatingConstructor());
248501af97d3SDimitry Andric 
248645b53394SDimitry Andric   Address ThisPtr = LoadCXXThisAddress();
248701af97d3SDimitry Andric 
2488180abc3dSDimitry Andric   AggValueSlot AggSlot =
248945b53394SDimitry Andric     AggValueSlot::forAddr(ThisPtr, Qualifiers(),
249036981b17SDimitry Andric                           AggValueSlot::IsDestructed,
249136981b17SDimitry Andric                           AggValueSlot::DoesNotNeedGCBarriers,
249248675466SDimitry Andric                           AggValueSlot::IsNotAliased,
2493c7e70c43SDimitry Andric                           AggValueSlot::MayOverlap,
2494c7e70c43SDimitry Andric                           AggValueSlot::IsNotZeroed,
2495c7e70c43SDimitry Andric                           // Checks are made by the code that calls constructor.
2496c7e70c43SDimitry Andric                           AggValueSlot::IsSanitizerChecked);
249701af97d3SDimitry Andric 
249801af97d3SDimitry Andric   EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot);
249901af97d3SDimitry Andric 
250029cafa66SDimitry Andric   const CXXRecordDecl *ClassDecl = Ctor->getParent();
2501dbe13110SDimitry Andric   if (CGM.getLangOpts().Exceptions && !ClassDecl->hasTrivialDestructor()) {
250229cafa66SDimitry Andric     CXXDtorType Type =
250329cafa66SDimitry Andric       CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base;
250429cafa66SDimitry Andric 
250529cafa66SDimitry Andric     EHStack.pushCleanup<CallDelegatingCtorDtor>(EHCleanup,
250629cafa66SDimitry Andric                                                 ClassDecl->getDestructor(),
250729cafa66SDimitry Andric                                                 ThisPtr, Type);
250829cafa66SDimitry Andric   }
250929cafa66SDimitry Andric }
251001af97d3SDimitry Andric 
EmitCXXDestructorCall(const CXXDestructorDecl * DD,CXXDtorType Type,bool ForVirtualBase,bool Delegating,Address This,QualType ThisTy)2511ee791ddeSRoman Divacky void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
2512ee791ddeSRoman Divacky                                             CXXDtorType Type,
25130883ccd9SRoman Divacky                                             bool ForVirtualBase,
251422989816SDimitry Andric                                             bool Delegating, Address This,
251522989816SDimitry Andric                                             QualType ThisTy) {
25169f4dbff6SDimitry Andric   CGM.getCXXABI().EmitDestructorCall(*this, DD, Type, ForVirtualBase,
251722989816SDimitry Andric                                      Delegating, This, ThisTy);
2518ee791ddeSRoman Divacky }
2519ee791ddeSRoman Divacky 
25203d1dcd9bSDimitry Andric namespace {
252145b53394SDimitry Andric   struct CallLocalDtor final : EHScopeStack::Cleanup {
25223d1dcd9bSDimitry Andric     const CXXDestructorDecl *Dtor;
252345b53394SDimitry Andric     Address Addr;
252422989816SDimitry Andric     QualType Ty;
25253d1dcd9bSDimitry Andric 
CallLocalDtor__anonf1d54d130611::CallLocalDtor252622989816SDimitry Andric     CallLocalDtor(const CXXDestructorDecl *D, Address Addr, QualType Ty)
252722989816SDimitry Andric         : Dtor(D), Addr(Addr), Ty(Ty) {}
25283d1dcd9bSDimitry Andric 
Emit__anonf1d54d130611::CallLocalDtor25299f4dbff6SDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
25303d1dcd9bSDimitry Andric       CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
2531809500fcSDimitry Andric                                 /*ForVirtualBase=*/false,
253222989816SDimitry Andric                                 /*Delegating=*/false, Addr, Ty);
25333d1dcd9bSDimitry Andric     }
25343d1dcd9bSDimitry Andric   };
25352b6b257fSDimitry Andric } // end anonymous namespace
25363d1dcd9bSDimitry Andric 
PushDestructorCleanup(const CXXDestructorDecl * D,QualType T,Address Addr)25373d1dcd9bSDimitry Andric void CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D,
253822989816SDimitry Andric                                             QualType T, Address Addr) {
253922989816SDimitry Andric   EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr, T);
25403d1dcd9bSDimitry Andric }
25413d1dcd9bSDimitry Andric 
PushDestructorCleanup(QualType T,Address Addr)254245b53394SDimitry Andric void CodeGenFunction::PushDestructorCleanup(QualType T, Address Addr) {
25434ba67500SRoman Divacky   CXXRecordDecl *ClassDecl = T->getAsCXXRecordDecl();
25444ba67500SRoman Divacky   if (!ClassDecl) return;
25454ba67500SRoman Divacky   if (ClassDecl->hasTrivialDestructor()) return;
25464ba67500SRoman Divacky 
25474ba67500SRoman Divacky   const CXXDestructorDecl *D = ClassDecl->getDestructor();
254801af97d3SDimitry Andric   assert(D && D->isUsed() && "destructor not marked as used!");
254922989816SDimitry Andric   PushDestructorCleanup(D, T, Addr);
25504ba67500SRoman Divacky }
25514ba67500SRoman Divacky 
InitializeVTablePointer(const VPtr & Vptr)255245b53394SDimitry Andric void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) {
255311d2b2d2SRoman Divacky   // Compute the address point.
2554bfef3995SDimitry Andric   llvm::Value *VTableAddressPoint =
2555bfef3995SDimitry Andric       CGM.getCXXABI().getVTableAddressPointInStructor(
255645b53394SDimitry Andric           *this, Vptr.VTableClass, Vptr.Base, Vptr.NearestVBase);
255745b53394SDimitry Andric 
2558bfef3995SDimitry Andric   if (!VTableAddressPoint)
2559bfef3995SDimitry Andric     return;
2560ee791ddeSRoman Divacky 
256111d2b2d2SRoman Divacky   // Compute where to store the address point.
25629f4dbff6SDimitry Andric   llvm::Value *VirtualOffset = nullptr;
256301af97d3SDimitry Andric   CharUnits NonVirtualOffset = CharUnits::Zero();
2564ee791ddeSRoman Divacky 
256545b53394SDimitry Andric   if (CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*this, Vptr)) {
256611d2b2d2SRoman Divacky     // We need to use the virtual base offset offset because the virtual base
256711d2b2d2SRoman Divacky     // might have a different offset in the most derived class.
256845b53394SDimitry Andric 
256945b53394SDimitry Andric     VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(
257045b53394SDimitry Andric         *this, LoadCXXThisAddress(), Vptr.VTableClass, Vptr.NearestVBase);
257145b53394SDimitry Andric     NonVirtualOffset = Vptr.OffsetFromNearestVBase;
257211d2b2d2SRoman Divacky   } else {
25730883ccd9SRoman Divacky     // We can just use the base offset in the complete class.
257445b53394SDimitry Andric     NonVirtualOffset = Vptr.Base.getBaseOffset();
257511d2b2d2SRoman Divacky   }
257611d2b2d2SRoman Divacky 
25770883ccd9SRoman Divacky   // Apply the offsets.
257845b53394SDimitry Andric   Address VTableField = LoadCXXThisAddress();
257901af97d3SDimitry Andric   if (!NonVirtualOffset.isZero() || VirtualOffset)
258045b53394SDimitry Andric     VTableField = ApplyNonVirtualAndVirtualOffset(
258145b53394SDimitry Andric         *this, VTableField, NonVirtualOffset, VirtualOffset, Vptr.VTableClass,
258245b53394SDimitry Andric         Vptr.NearestVBase);
25830883ccd9SRoman Divacky 
258406d4ba38SDimitry Andric   // Finally, store the address point. Use the same LLVM types as the field to
258506d4ba38SDimitry Andric   // support optimization.
2586b60736ecSDimitry Andric   unsigned GlobalsAS = CGM.getDataLayout().getDefaultGlobalsAddressSpace();
25877fa27ce4SDimitry Andric   llvm::Type *PtrTy = llvm::PointerType::get(CGM.getLLVMContext(), GlobalsAS);
2588e3b55780SDimitry Andric   // vtable field is derived from `this` pointer, therefore they should be in
2589c0981da4SDimitry Andric   // the same addr space. Note that this might not be LLVM address space 0.
25907fa27ce4SDimitry Andric   VTableField = VTableField.withElementType(PtrTy);
259145b53394SDimitry Andric 
2592ac9a064cSDimitry Andric   if (auto AuthenticationInfo = CGM.getVTablePointerAuthInfo(
2593ac9a064cSDimitry Andric           this, Vptr.Base.getBase(), VTableField.emitRawPointer(*this)))
2594ac9a064cSDimitry Andric     VTableAddressPoint =
2595ac9a064cSDimitry Andric         EmitPointerAuthSign(*AuthenticationInfo, VTableAddressPoint);
2596ac9a064cSDimitry Andric 
2597dbe13110SDimitry Andric   llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField);
25987fa27ce4SDimitry Andric   TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(PtrTy);
2599461a67faSDimitry Andric   CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
260045b53394SDimitry Andric   if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
260145b53394SDimitry Andric       CGM.getCodeGenOpts().StrictVTablePointers)
260245b53394SDimitry Andric     CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.VTableClass);
260311d2b2d2SRoman Divacky }
260411d2b2d2SRoman Divacky 
260545b53394SDimitry Andric CodeGenFunction::VPtrsVector
getVTablePointers(const CXXRecordDecl * VTableClass)260645b53394SDimitry Andric CodeGenFunction::getVTablePointers(const CXXRecordDecl *VTableClass) {
260745b53394SDimitry Andric   CodeGenFunction::VPtrsVector VPtrsResult;
260845b53394SDimitry Andric   VisitedVirtualBasesSetTy VBases;
260945b53394SDimitry Andric   getVTablePointers(BaseSubobject(VTableClass, CharUnits::Zero()),
261045b53394SDimitry Andric                     /*NearestVBase=*/nullptr,
261145b53394SDimitry Andric                     /*OffsetFromNearestVBase=*/CharUnits::Zero(),
261245b53394SDimitry Andric                     /*BaseIsNonVirtualPrimaryBase=*/false, VTableClass, VBases,
261345b53394SDimitry Andric                     VPtrsResult);
261445b53394SDimitry Andric   return VPtrsResult;
261545b53394SDimitry Andric }
261645b53394SDimitry Andric 
getVTablePointers(BaseSubobject Base,const CXXRecordDecl * NearestVBase,CharUnits OffsetFromNearestVBase,bool BaseIsNonVirtualPrimaryBase,const CXXRecordDecl * VTableClass,VisitedVirtualBasesSetTy & VBases,VPtrsVector & Vptrs)261745b53394SDimitry Andric void CodeGenFunction::getVTablePointers(BaseSubobject Base,
26180883ccd9SRoman Divacky                                         const CXXRecordDecl *NearestVBase,
261901af97d3SDimitry Andric                                         CharUnits OffsetFromNearestVBase,
262011d2b2d2SRoman Divacky                                         bool BaseIsNonVirtualPrimaryBase,
262111d2b2d2SRoman Divacky                                         const CXXRecordDecl *VTableClass,
262245b53394SDimitry Andric                                         VisitedVirtualBasesSetTy &VBases,
262345b53394SDimitry Andric                                         VPtrsVector &Vptrs) {
262411d2b2d2SRoman Divacky   // If this base is a non-virtual primary base the address point has already
262511d2b2d2SRoman Divacky   // been set.
262611d2b2d2SRoman Divacky   if (!BaseIsNonVirtualPrimaryBase) {
262711d2b2d2SRoman Divacky     // Initialize the vtable pointer for this base.
262845b53394SDimitry Andric     VPtr Vptr = {Base, NearestVBase, OffsetFromNearestVBase, VTableClass};
262945b53394SDimitry Andric     Vptrs.push_back(Vptr);
263011d2b2d2SRoman Divacky   }
263111d2b2d2SRoman Divacky 
263211d2b2d2SRoman Divacky   const CXXRecordDecl *RD = Base.getBase();
263311d2b2d2SRoman Divacky 
263411d2b2d2SRoman Divacky   // Traverse bases.
26359f4dbff6SDimitry Andric   for (const auto &I : RD->bases()) {
2636519fc96cSDimitry Andric     auto *BaseDecl =
2637519fc96cSDimitry Andric         cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
263811d2b2d2SRoman Divacky 
263911d2b2d2SRoman Divacky     // Ignore classes without a vtable.
264011d2b2d2SRoman Divacky     if (!BaseDecl->isDynamicClass())
264111d2b2d2SRoman Divacky       continue;
264211d2b2d2SRoman Divacky 
264301af97d3SDimitry Andric     CharUnits BaseOffset;
264401af97d3SDimitry Andric     CharUnits BaseOffsetFromNearestVBase;
264511d2b2d2SRoman Divacky     bool BaseDeclIsNonVirtualPrimaryBase;
264611d2b2d2SRoman Divacky 
26479f4dbff6SDimitry Andric     if (I.isVirtual()) {
264811d2b2d2SRoman Divacky       // Check if we've visited this virtual base before.
264906d4ba38SDimitry Andric       if (!VBases.insert(BaseDecl).second)
265011d2b2d2SRoman Divacky         continue;
265111d2b2d2SRoman Divacky 
265211d2b2d2SRoman Divacky       const ASTRecordLayout &Layout =
265311d2b2d2SRoman Divacky         getContext().getASTRecordLayout(VTableClass);
265411d2b2d2SRoman Divacky 
265501af97d3SDimitry Andric       BaseOffset = Layout.getVBaseClassOffset(BaseDecl);
265601af97d3SDimitry Andric       BaseOffsetFromNearestVBase = CharUnits::Zero();
265711d2b2d2SRoman Divacky       BaseDeclIsNonVirtualPrimaryBase = false;
265811d2b2d2SRoman Divacky     } else {
265911d2b2d2SRoman Divacky       const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
266011d2b2d2SRoman Divacky 
266101af97d3SDimitry Andric       BaseOffset = Base.getBaseOffset() + Layout.getBaseClassOffset(BaseDecl);
26620883ccd9SRoman Divacky       BaseOffsetFromNearestVBase =
266301af97d3SDimitry Andric         OffsetFromNearestVBase + Layout.getBaseClassOffset(BaseDecl);
266411d2b2d2SRoman Divacky       BaseDeclIsNonVirtualPrimaryBase = Layout.getPrimaryBase() == BaseDecl;
266511d2b2d2SRoman Divacky     }
266611d2b2d2SRoman Divacky 
266745b53394SDimitry Andric     getVTablePointers(
266845b53394SDimitry Andric         BaseSubobject(BaseDecl, BaseOffset),
266945b53394SDimitry Andric         I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase,
267045b53394SDimitry Andric         BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs);
267111d2b2d2SRoman Divacky   }
267211d2b2d2SRoman Divacky }
267311d2b2d2SRoman Divacky 
InitializeVTablePointers(const CXXRecordDecl * RD)267411d2b2d2SRoman Divacky void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) {
267511d2b2d2SRoman Divacky   // Ignore classes without a vtable.
267611d2b2d2SRoman Divacky   if (!RD->isDynamicClass())
267711d2b2d2SRoman Divacky     return;
267811d2b2d2SRoman Divacky 
267911d2b2d2SRoman Divacky   // Initialize the vtable pointers for this class and all of its bases.
268045b53394SDimitry Andric   if (CGM.getCXXABI().doStructorsInitializeVPtrs(RD))
268145b53394SDimitry Andric     for (const VPtr &Vptr : getVTablePointers(RD))
268245b53394SDimitry Andric       InitializeVTablePointer(Vptr);
2683bfef3995SDimitry Andric 
2684bfef3995SDimitry Andric   if (RD->getNumVBases())
2685bfef3995SDimitry Andric     CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*this, RD);
2686ee791ddeSRoman Divacky }
2687bca07a45SDimitry Andric 
GetVTablePtr(Address This,llvm::Type * VTableTy,const CXXRecordDecl * RD,VTableAuthMode AuthMode)268845b53394SDimitry Andric llvm::Value *CodeGenFunction::GetVTablePtr(Address This,
268945b53394SDimitry Andric                                            llvm::Type *VTableTy,
2690ac9a064cSDimitry Andric                                            const CXXRecordDecl *RD,
2691ac9a064cSDimitry Andric                                            VTableAuthMode AuthMode) {
26927fa27ce4SDimitry Andric   Address VTablePtrSrc = This.withElementType(VTableTy);
2693dbe13110SDimitry Andric   llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable");
2694461a67faSDimitry Andric   TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy);
2695461a67faSDimitry Andric   CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo);
269645b53394SDimitry Andric 
2697ac9a064cSDimitry Andric   if (auto AuthenticationInfo =
2698ac9a064cSDimitry Andric           CGM.getVTablePointerAuthInfo(this, RD, This.emitRawPointer(*this))) {
2699ac9a064cSDimitry Andric     if (AuthMode != VTableAuthMode::UnsafeUbsanStrip) {
2700ac9a064cSDimitry Andric       VTable = cast<llvm::Instruction>(
2701ac9a064cSDimitry Andric           EmitPointerAuthAuth(*AuthenticationInfo, VTable));
2702ac9a064cSDimitry Andric       if (AuthMode == VTableAuthMode::MustTrap) {
2703ac9a064cSDimitry Andric         // This is clearly suboptimal but until we have an ability
2704ac9a064cSDimitry Andric         // to rely on the authentication intrinsic trapping and force
2705ac9a064cSDimitry Andric         // an authentication to occur we don't really have a choice.
2706ac9a064cSDimitry Andric         VTable =
2707ac9a064cSDimitry Andric             cast<llvm::Instruction>(Builder.CreateBitCast(VTable, Int8PtrTy));
2708ac9a064cSDimitry Andric         Builder.CreateLoad(RawAddress(VTable, Int8Ty, CGM.getPointerAlign()),
2709ac9a064cSDimitry Andric                            /* IsVolatile */ true);
2710ac9a064cSDimitry Andric       }
2711ac9a064cSDimitry Andric     } else {
2712ac9a064cSDimitry Andric       VTable = cast<llvm::Instruction>(EmitPointerAuthAuth(
2713ac9a064cSDimitry Andric           CGPointerAuthInfo(0, PointerAuthenticationMode::Strip, false, false,
2714ac9a064cSDimitry Andric                             nullptr),
2715ac9a064cSDimitry Andric           VTable));
2716ac9a064cSDimitry Andric     }
2717ac9a064cSDimitry Andric   }
2718ac9a064cSDimitry Andric 
271945b53394SDimitry Andric   if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
272045b53394SDimitry Andric       CGM.getCodeGenOpts().StrictVTablePointers)
272145b53394SDimitry Andric     CGM.DecorateInstructionWithInvariantGroup(VTable, RD);
272245b53394SDimitry Andric 
2723dbe13110SDimitry Andric   return VTable;
2724bca07a45SDimitry Andric }
272529cafa66SDimitry Andric 
27265e20cdd8SDimitry Andric // If a class has a single non-virtual base and does not introduce or override
27275e20cdd8SDimitry Andric // virtual member functions or fields, it will have the same layout as its base.
27285e20cdd8SDimitry Andric // This function returns the least derived such class.
27295e20cdd8SDimitry Andric //
27305e20cdd8SDimitry Andric // Casting an instance of a base class to such a derived class is technically
27315e20cdd8SDimitry Andric // undefined behavior, but it is a relatively common hack for introducing member
27325e20cdd8SDimitry Andric // functions on class instances with specific properties (e.g. llvm::Operator)
27335e20cdd8SDimitry Andric // that works under most compilers and should not have security implications, so
27345e20cdd8SDimitry Andric // we allow it by default. It can be disabled with -fsanitize=cfi-cast-strict.
27355e20cdd8SDimitry Andric static const CXXRecordDecl *
LeastDerivedClassWithSameLayout(const CXXRecordDecl * RD)27365e20cdd8SDimitry Andric LeastDerivedClassWithSameLayout(const CXXRecordDecl *RD) {
27375e20cdd8SDimitry Andric   if (!RD->field_empty())
27385e20cdd8SDimitry Andric     return RD;
27395e20cdd8SDimitry Andric 
27405e20cdd8SDimitry Andric   if (RD->getNumVBases() != 0)
27415e20cdd8SDimitry Andric     return RD;
27425e20cdd8SDimitry Andric 
27435e20cdd8SDimitry Andric   if (RD->getNumBases() != 1)
27445e20cdd8SDimitry Andric     return RD;
27455e20cdd8SDimitry Andric 
27465e20cdd8SDimitry Andric   for (const CXXMethodDecl *MD : RD->methods()) {
27475e20cdd8SDimitry Andric     if (MD->isVirtual()) {
27485e20cdd8SDimitry Andric       // Virtual member functions are only ok if they are implicit destructors
27495e20cdd8SDimitry Andric       // because the implicit destructor will have the same semantics as the
27505e20cdd8SDimitry Andric       // base class's destructor if no fields are added.
27515e20cdd8SDimitry Andric       if (isa<CXXDestructorDecl>(MD) && MD->isImplicit())
27525e20cdd8SDimitry Andric         continue;
27535e20cdd8SDimitry Andric       return RD;
27545e20cdd8SDimitry Andric     }
27555e20cdd8SDimitry Andric   }
27565e20cdd8SDimitry Andric 
27575e20cdd8SDimitry Andric   return LeastDerivedClassWithSameLayout(
27585e20cdd8SDimitry Andric       RD->bases_begin()->getType()->getAsCXXRecordDecl());
27595e20cdd8SDimitry Andric }
27605e20cdd8SDimitry Andric 
EmitTypeMetadataCodeForVCall(const CXXRecordDecl * RD,llvm::Value * VTable,SourceLocation Loc)27612b6b257fSDimitry Andric void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD,
27622b6b257fSDimitry Andric                                                    llvm::Value *VTable,
27632b6b257fSDimitry Andric                                                    SourceLocation Loc) {
2764461a67faSDimitry Andric   if (SanOpts.has(SanitizerKind::CFIVCall))
2765461a67faSDimitry Andric     EmitVTablePtrCheckForCall(RD, VTable, CodeGenFunction::CFITCK_VCall, Loc);
2766461a67faSDimitry Andric   else if (CGM.getCodeGenOpts().WholeProgramVTables &&
2767145449b1SDimitry Andric            // Don't insert type test assumes if we are forcing public
2768cfca06d7SDimitry Andric            // visibility.
2769145449b1SDimitry Andric            !CGM.AlwaysHasLTOVisibilityPublic(RD)) {
277008e8dd7bSDimitry Andric     QualType Ty = QualType(RD->getTypeForDecl(), 0);
277108e8dd7bSDimitry Andric     llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(Ty);
27722b6b257fSDimitry Andric     llvm::Value *TypeId =
27732b6b257fSDimitry Andric         llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
27742b6b257fSDimitry Andric 
277508e8dd7bSDimitry Andric     // If we already know that the call has hidden LTO visibility, emit
277608e8dd7bSDimitry Andric     // @llvm.type.test(). Otherwise emit @llvm.public.type.test(), which WPD
277708e8dd7bSDimitry Andric     // will convert to @llvm.type.test() if we assert at link time that we have
277808e8dd7bSDimitry Andric     // whole program visibility.
277908e8dd7bSDimitry Andric     llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
278008e8dd7bSDimitry Andric                                   ? llvm::Intrinsic::type_test
278108e8dd7bSDimitry Andric                                   : llvm::Intrinsic::public_type_test;
27822b6b257fSDimitry Andric     llvm::Value *TypeTest =
2783b1c73532SDimitry Andric         Builder.CreateCall(CGM.getIntrinsic(IID), {VTable, TypeId});
27842b6b257fSDimitry Andric     Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest);
27852b6b257fSDimitry Andric   }
27862b6b257fSDimitry Andric }
27872b6b257fSDimitry Andric 
EmitVTablePtrCheckForCall(const CXXRecordDecl * RD,llvm::Value * VTable,CFITypeCheckKind TCK,SourceLocation Loc)27882b6b257fSDimitry Andric void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD,
27892e645aa5SDimitry Andric                                                 llvm::Value *VTable,
27902e645aa5SDimitry Andric                                                 CFITypeCheckKind TCK,
27912e645aa5SDimitry Andric                                                 SourceLocation Loc) {
27925e20cdd8SDimitry Andric   if (!SanOpts.has(SanitizerKind::CFICastStrict))
27932b6b257fSDimitry Andric     RD = LeastDerivedClassWithSameLayout(RD);
27945e20cdd8SDimitry Andric 
27952b6b257fSDimitry Andric   EmitVTablePtrCheck(RD, VTable, TCK, Loc);
27965e20cdd8SDimitry Andric }
27975e20cdd8SDimitry Andric 
EmitVTablePtrCheckForCast(QualType T,Address Derived,bool MayBeNull,CFITypeCheckKind TCK,SourceLocation Loc)2798145449b1SDimitry Andric void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived,
27992e645aa5SDimitry Andric                                                 bool MayBeNull,
28002e645aa5SDimitry Andric                                                 CFITypeCheckKind TCK,
28012e645aa5SDimitry Andric                                                 SourceLocation Loc) {
28025e20cdd8SDimitry Andric   if (!getLangOpts().CPlusPlus)
28035e20cdd8SDimitry Andric     return;
28045e20cdd8SDimitry Andric 
28055e20cdd8SDimitry Andric   auto *ClassTy = T->getAs<RecordType>();
28065e20cdd8SDimitry Andric   if (!ClassTy)
28075e20cdd8SDimitry Andric     return;
28085e20cdd8SDimitry Andric 
28095e20cdd8SDimitry Andric   const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassTy->getDecl());
28105e20cdd8SDimitry Andric 
28115e20cdd8SDimitry Andric   if (!ClassDecl->isCompleteDefinition() || !ClassDecl->isDynamicClass())
28125e20cdd8SDimitry Andric     return;
28135e20cdd8SDimitry Andric 
28145e20cdd8SDimitry Andric   if (!SanOpts.has(SanitizerKind::CFICastStrict))
28155e20cdd8SDimitry Andric     ClassDecl = LeastDerivedClassWithSameLayout(ClassDecl);
28165e20cdd8SDimitry Andric 
281745b53394SDimitry Andric   llvm::BasicBlock *ContBlock = nullptr;
28185e20cdd8SDimitry Andric 
28195e20cdd8SDimitry Andric   if (MayBeNull) {
28205e20cdd8SDimitry Andric     llvm::Value *DerivedNotNull =
2821ac9a064cSDimitry Andric         Builder.CreateIsNotNull(Derived.emitRawPointer(*this), "cast.nonnull");
28225e20cdd8SDimitry Andric 
28235e20cdd8SDimitry Andric     llvm::BasicBlock *CheckBlock = createBasicBlock("cast.check");
28245e20cdd8SDimitry Andric     ContBlock = createBasicBlock("cast.cont");
28255e20cdd8SDimitry Andric 
28265e20cdd8SDimitry Andric     Builder.CreateCondBr(DerivedNotNull, CheckBlock, ContBlock);
28275e20cdd8SDimitry Andric 
28285e20cdd8SDimitry Andric     EmitBlock(CheckBlock);
28295e20cdd8SDimitry Andric   }
28305e20cdd8SDimitry Andric 
2831461a67faSDimitry Andric   llvm::Value *VTable;
2832145449b1SDimitry Andric   std::tie(VTable, ClassDecl) =
2833145449b1SDimitry Andric       CGM.getCXXABI().LoadVTablePtr(*this, Derived, ClassDecl);
283445b53394SDimitry Andric 
28352e645aa5SDimitry Andric   EmitVTablePtrCheck(ClassDecl, VTable, TCK, Loc);
28365e20cdd8SDimitry Andric 
28375e20cdd8SDimitry Andric   if (MayBeNull) {
28385e20cdd8SDimitry Andric     Builder.CreateBr(ContBlock);
28395e20cdd8SDimitry Andric     EmitBlock(ContBlock);
28405e20cdd8SDimitry Andric   }
28415e20cdd8SDimitry Andric }
28425e20cdd8SDimitry Andric 
EmitVTablePtrCheck(const CXXRecordDecl * RD,llvm::Value * VTable,CFITypeCheckKind TCK,SourceLocation Loc)28435e20cdd8SDimitry Andric void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
28442e645aa5SDimitry Andric                                          llvm::Value *VTable,
28452e645aa5SDimitry Andric                                          CFITypeCheckKind TCK,
28462e645aa5SDimitry Andric                                          SourceLocation Loc) {
28472b6b257fSDimitry Andric   if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
28482b6b257fSDimitry Andric       !CGM.HasHiddenLTOVisibility(RD))
28492b6b257fSDimitry Andric     return;
28502b6b257fSDimitry Andric 
2851461a67faSDimitry Andric   SanitizerMask M;
28522b6b257fSDimitry Andric   llvm::SanitizerStatKind SSK;
28532b6b257fSDimitry Andric   switch (TCK) {
28542b6b257fSDimitry Andric   case CFITCK_VCall:
2855461a67faSDimitry Andric     M = SanitizerKind::CFIVCall;
28562b6b257fSDimitry Andric     SSK = llvm::SanStat_CFI_VCall;
28572b6b257fSDimitry Andric     break;
28582b6b257fSDimitry Andric   case CFITCK_NVCall:
2859461a67faSDimitry Andric     M = SanitizerKind::CFINVCall;
28602b6b257fSDimitry Andric     SSK = llvm::SanStat_CFI_NVCall;
28612b6b257fSDimitry Andric     break;
28622b6b257fSDimitry Andric   case CFITCK_DerivedCast:
2863461a67faSDimitry Andric     M = SanitizerKind::CFIDerivedCast;
28642b6b257fSDimitry Andric     SSK = llvm::SanStat_CFI_DerivedCast;
28652b6b257fSDimitry Andric     break;
28662b6b257fSDimitry Andric   case CFITCK_UnrelatedCast:
2867461a67faSDimitry Andric     M = SanitizerKind::CFIUnrelatedCast;
28682b6b257fSDimitry Andric     SSK = llvm::SanStat_CFI_UnrelatedCast;
28692b6b257fSDimitry Andric     break;
28702b6b257fSDimitry Andric   case CFITCK_ICall:
287148675466SDimitry Andric   case CFITCK_NVMFCall:
287248675466SDimitry Andric   case CFITCK_VMFCall:
287348675466SDimitry Andric     llvm_unreachable("unexpected sanitizer kind");
28742b6b257fSDimitry Andric   }
2875461a67faSDimitry Andric 
2876461a67faSDimitry Andric   std::string TypeName = RD->getQualifiedNameAsString();
2877344a3780SDimitry Andric   if (getContext().getNoSanitizeList().containsType(M, TypeName))
2878461a67faSDimitry Andric     return;
2879461a67faSDimitry Andric 
2880461a67faSDimitry Andric   SanitizerScope SanScope(this);
28812b6b257fSDimitry Andric   EmitSanitizerStatReport(SSK);
28822e645aa5SDimitry Andric 
288345b53394SDimitry Andric   llvm::Metadata *MD =
288445b53394SDimitry Andric       CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
28852b6b257fSDimitry Andric   llvm::Value *TypeId = llvm::MetadataAsValue::get(getLLVMContext(), MD);
28865e20cdd8SDimitry Andric 
28872b6b257fSDimitry Andric   llvm::Value *TypeTest = Builder.CreateCall(
2888b1c73532SDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, TypeId});
288945b53394SDimitry Andric 
28902e645aa5SDimitry Andric   llvm::Constant *StaticData[] = {
28912b6b257fSDimitry Andric       llvm::ConstantInt::get(Int8Ty, TCK),
28922e645aa5SDimitry Andric       EmitCheckSourceLocation(Loc),
28932e645aa5SDimitry Andric       EmitCheckTypeDescriptor(QualType(RD->getTypeForDecl(), 0)),
28942e645aa5SDimitry Andric   };
28952b6b257fSDimitry Andric 
28962b6b257fSDimitry Andric   auto CrossDsoTypeId = CGM.CreateCrossDsoCfiTypeId(MD);
28972b6b257fSDimitry Andric   if (CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) {
2898b1c73532SDimitry Andric     EmitCfiSlowPathCheck(M, TypeTest, CrossDsoTypeId, VTable, StaticData);
28992b6b257fSDimitry Andric     return;
29002b6b257fSDimitry Andric   }
29012b6b257fSDimitry Andric 
29022b6b257fSDimitry Andric   if (CGM.getCodeGenOpts().SanitizeTrap.has(M)) {
2903b60736ecSDimitry Andric     EmitTrapCheck(TypeTest, SanitizerHandler::CFICheckFail);
29042b6b257fSDimitry Andric     return;
29052b6b257fSDimitry Andric   }
29062b6b257fSDimitry Andric 
29072b6b257fSDimitry Andric   llvm::Value *AllVtables = llvm::MetadataAsValue::get(
29082b6b257fSDimitry Andric       CGM.getLLVMContext(),
29092b6b257fSDimitry Andric       llvm::MDString::get(CGM.getLLVMContext(), "all-vtables"));
29102b6b257fSDimitry Andric   llvm::Value *ValidVtable = Builder.CreateCall(
2911b1c73532SDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
2912bab175ecSDimitry Andric   EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail,
2913b1c73532SDimitry Andric             StaticData, {VTable, ValidVtable});
29142b6b257fSDimitry Andric }
29152b6b257fSDimitry Andric 
ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl * RD)29162b6b257fSDimitry Andric bool CodeGenFunction::ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD) {
29172b6b257fSDimitry Andric   if (!CGM.getCodeGenOpts().WholeProgramVTables ||
29182b6b257fSDimitry Andric       !CGM.HasHiddenLTOVisibility(RD))
29192b6b257fSDimitry Andric     return false;
29202b6b257fSDimitry Andric 
2921519fc96cSDimitry Andric   if (CGM.getCodeGenOpts().VirtualFunctionElimination)
2922519fc96cSDimitry Andric     return true;
2923519fc96cSDimitry Andric 
2924519fc96cSDimitry Andric   if (!SanOpts.has(SanitizerKind::CFIVCall) ||
2925519fc96cSDimitry Andric       !CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIVCall))
2926519fc96cSDimitry Andric     return false;
2927519fc96cSDimitry Andric 
29282b6b257fSDimitry Andric   std::string TypeName = RD->getQualifiedNameAsString();
2929344a3780SDimitry Andric   return !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall,
2930344a3780SDimitry Andric                                                         TypeName);
29312b6b257fSDimitry Andric }
29322b6b257fSDimitry Andric 
EmitVTableTypeCheckedLoad(const CXXRecordDecl * RD,llvm::Value * VTable,llvm::Type * VTableTy,uint64_t VTableByteOffset)29332b6b257fSDimitry Andric llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
2934145449b1SDimitry Andric     const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy,
2935145449b1SDimitry Andric     uint64_t VTableByteOffset) {
29362b6b257fSDimitry Andric   SanitizerScope SanScope(this);
29372b6b257fSDimitry Andric 
29382b6b257fSDimitry Andric   EmitSanitizerStatReport(llvm::SanStat_CFI_VCall);
29392b6b257fSDimitry Andric 
29402b6b257fSDimitry Andric   llvm::Metadata *MD =
29412b6b257fSDimitry Andric       CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
29422b6b257fSDimitry Andric   llvm::Value *TypeId = llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
29432b6b257fSDimitry Andric 
29442b6b257fSDimitry Andric   llvm::Value *CheckedLoad = Builder.CreateCall(
29452b6b257fSDimitry Andric       CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
2946b1c73532SDimitry Andric       {VTable, llvm::ConstantInt::get(Int32Ty, VTableByteOffset), TypeId});
29472b6b257fSDimitry Andric   llvm::Value *CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
29482b6b257fSDimitry Andric 
2949519fc96cSDimitry Andric   std::string TypeName = RD->getQualifiedNameAsString();
2950519fc96cSDimitry Andric   if (SanOpts.has(SanitizerKind::CFIVCall) &&
2951344a3780SDimitry Andric       !getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall,
2952344a3780SDimitry Andric                                                      TypeName)) {
29532b6b257fSDimitry Andric     EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIVCall),
2954519fc96cSDimitry Andric               SanitizerHandler::CFICheckFail, {}, {});
2955519fc96cSDimitry Andric   }
29562b6b257fSDimitry Andric 
29576f8fc217SDimitry Andric   return Builder.CreateBitCast(Builder.CreateExtractValue(CheckedLoad, 0),
2958145449b1SDimitry Andric                                VTableTy);
29595e20cdd8SDimitry Andric }
296029cafa66SDimitry Andric 
EmitForwardingCallToLambda(const CXXMethodDecl * callOperator,CallArgList & callArgs,const CGFunctionInfo * calleeFnInfo,llvm::Constant * calleePtr)2961bfef3995SDimitry Andric void CodeGenFunction::EmitForwardingCallToLambda(
2962b1c73532SDimitry Andric     const CXXMethodDecl *callOperator, CallArgList &callArgs,
2963b1c73532SDimitry Andric     const CGFunctionInfo *calleeFnInfo, llvm::Constant *calleePtr) {
2964dbe13110SDimitry Andric   // Get the address of the call operator.
2965b1c73532SDimitry Andric   if (!calleeFnInfo)
2966b1c73532SDimitry Andric     calleeFnInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
2967b1c73532SDimitry Andric 
2968b1c73532SDimitry Andric   if (!calleePtr)
2969b1c73532SDimitry Andric     calleePtr =
297056d91b49SDimitry Andric         CGM.GetAddrOfFunction(GlobalDecl(callOperator),
2971b1c73532SDimitry Andric                               CGM.getTypes().GetFunctionType(*calleeFnInfo));
2972dbe13110SDimitry Andric 
297356d91b49SDimitry Andric   // Prepare the return slot.
297456d91b49SDimitry Andric   const FunctionProtoType *FPT =
297556d91b49SDimitry Andric     callOperator->getType()->castAs<FunctionProtoType>();
29769f4dbff6SDimitry Andric   QualType resultType = FPT->getReturnType();
297756d91b49SDimitry Andric   ReturnValueSlot returnSlot;
297856d91b49SDimitry Andric   if (!resultType->isVoidType() &&
2979b1c73532SDimitry Andric       calleeFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
2980b1c73532SDimitry Andric       !hasScalarEvaluationKind(calleeFnInfo->getReturnType()))
2981cfca06d7SDimitry Andric     returnSlot =
2982cfca06d7SDimitry Andric         ReturnValueSlot(ReturnValue, resultType.isVolatileQualified(),
2983cfca06d7SDimitry Andric                         /*IsUnused=*/false, /*IsExternallyDestructed=*/true);
298456d91b49SDimitry Andric 
298556d91b49SDimitry Andric   // We don't need to separately arrange the call arguments because
298656d91b49SDimitry Andric   // the call can't be variadic anyway --- it's impossible to forward
298756d91b49SDimitry Andric   // variadic arguments.
2988dbe13110SDimitry Andric 
2989dbe13110SDimitry Andric   // Now emit our call.
2990676fbe81SDimitry Andric   auto callee = CGCallee::forDirect(calleePtr, GlobalDecl(callOperator));
2991b1c73532SDimitry Andric   RValue RV = EmitCall(*calleeFnInfo, callee, returnSlot, callArgs);
2992dbe13110SDimitry Andric 
299356d91b49SDimitry Andric   // If necessary, copy the returned value into the slot.
2994461a67faSDimitry Andric   if (!resultType->isVoidType() && returnSlot.isNull()) {
2995461a67faSDimitry Andric     if (getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType()) {
2996461a67faSDimitry Andric       RV = RValue::get(EmitARCRetainAutoreleasedReturnValue(RV.getScalarVal()));
2997461a67faSDimitry Andric     }
299856d91b49SDimitry Andric     EmitReturnOfRValue(RV, resultType);
2999461a67faSDimitry Andric   } else
3000809500fcSDimitry Andric     EmitBranchThroughCleanup(ReturnBlock);
3001dbe13110SDimitry Andric }
3002dbe13110SDimitry Andric 
EmitLambdaBlockInvokeBody()3003dbe13110SDimitry Andric void CodeGenFunction::EmitLambdaBlockInvokeBody() {
3004dbe13110SDimitry Andric   const BlockDecl *BD = BlockInfo->getBlockDecl();
3005dbe13110SDimitry Andric   const VarDecl *variable = BD->capture_begin()->getVariable();
3006dbe13110SDimitry Andric   const CXXRecordDecl *Lambda = variable->getType()->getAsCXXRecordDecl();
3007461a67faSDimitry Andric   const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator();
3008461a67faSDimitry Andric 
3009461a67faSDimitry Andric   if (CallOp->isVariadic()) {
3010461a67faSDimitry Andric     // FIXME: Making this work correctly is nasty because it requires either
3011461a67faSDimitry Andric     // cloning the body of the call operator or making the call operator
3012461a67faSDimitry Andric     // forward.
3013461a67faSDimitry Andric     CGM.ErrorUnsupported(CurCodeDecl, "lambda conversion to variadic function");
3014461a67faSDimitry Andric     return;
3015461a67faSDimitry Andric   }
3016dbe13110SDimitry Andric 
3017dbe13110SDimitry Andric   // Start building arguments for forwarding call
3018dbe13110SDimitry Andric   CallArgList CallArgs;
3019dbe13110SDimitry Andric 
3020dbe13110SDimitry Andric   QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda));
3021676fbe81SDimitry Andric   Address ThisPtr = GetAddrOfBlockDecl(variable);
3022ac9a064cSDimitry Andric   CallArgs.add(RValue::get(getAsNaturalPointerTo(ThisPtr, ThisType)), ThisType);
3023dbe13110SDimitry Andric 
3024dbe13110SDimitry Andric   // Add the rest of the parameters.
3025e3b55780SDimitry Andric   for (auto *param : BD->parameters())
3026676fbe81SDimitry Andric     EmitDelegateCallArg(CallArgs, param, param->getBeginLoc());
30279f4dbff6SDimitry Andric 
3028bfef3995SDimitry Andric   assert(!Lambda->isGenericLambda() &&
3029bfef3995SDimitry Andric             "generic lambda interconversion to block not implemented");
3030461a67faSDimitry Andric   EmitForwardingCallToLambda(CallOp, CallArgs);
3031dbe13110SDimitry Andric }
3032dbe13110SDimitry Andric 
EmitLambdaStaticInvokeBody(const CXXMethodDecl * MD)3033b1c73532SDimitry Andric void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) {
3034b1c73532SDimitry Andric   if (MD->isVariadic()) {
3035b1c73532SDimitry Andric     // FIXME: Making this work correctly is nasty because it requires either
3036b1c73532SDimitry Andric     // cloning the body of the call operator or making the call operator
3037b1c73532SDimitry Andric     // forward.
3038b1c73532SDimitry Andric     CGM.ErrorUnsupported(MD, "lambda conversion to variadic function");
3039b1c73532SDimitry Andric     return;
3040b1c73532SDimitry Andric   }
3041b1c73532SDimitry Andric 
3042dbe13110SDimitry Andric   const CXXRecordDecl *Lambda = MD->getParent();
3043dbe13110SDimitry Andric 
3044dbe13110SDimitry Andric   // Start building arguments for forwarding call
3045dbe13110SDimitry Andric   CallArgList CallArgs;
3046dbe13110SDimitry Andric 
3047e3b55780SDimitry Andric   QualType LambdaType = getContext().getRecordType(Lambda);
3048e3b55780SDimitry Andric   QualType ThisType = getContext().getPointerType(LambdaType);
3049e3b55780SDimitry Andric   Address ThisPtr = CreateMemTemp(LambdaType, "unused.capture");
3050ac9a064cSDimitry Andric   CallArgs.add(RValue::get(ThisPtr.emitRawPointer(*this)), ThisType);
3051dbe13110SDimitry Andric 
3052b1c73532SDimitry Andric   EmitLambdaDelegatingInvokeBody(MD, CallArgs);
3053b1c73532SDimitry Andric }
3054b1c73532SDimitry Andric 
EmitLambdaDelegatingInvokeBody(const CXXMethodDecl * MD,CallArgList & CallArgs)3055b1c73532SDimitry Andric void CodeGenFunction::EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD,
3056b1c73532SDimitry Andric                                                      CallArgList &CallArgs) {
3057b1c73532SDimitry Andric   // Add the rest of the forwarded parameters.
3058e3b55780SDimitry Andric   for (auto *Param : MD->parameters())
3059676fbe81SDimitry Andric     EmitDelegateCallArg(CallArgs, Param, Param->getBeginLoc());
30609f4dbff6SDimitry Andric 
3061b1c73532SDimitry Andric   const CXXRecordDecl *Lambda = MD->getParent();
3062bfef3995SDimitry Andric   const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator();
3063bfef3995SDimitry Andric   // For a generic lambda, find the corresponding call operator specialization
3064bfef3995SDimitry Andric   // to which the call to the static-invoker shall be forwarded.
3065bfef3995SDimitry Andric   if (Lambda->isGenericLambda()) {
3066bfef3995SDimitry Andric     assert(MD->isFunctionTemplateSpecialization());
3067bfef3995SDimitry Andric     const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs();
3068bfef3995SDimitry Andric     FunctionTemplateDecl *CallOpTemplate = CallOp->getDescribedFunctionTemplate();
30699f4dbff6SDimitry Andric     void *InsertPos = nullptr;
3070bfef3995SDimitry Andric     FunctionDecl *CorrespondingCallOpSpecialization =
30719f4dbff6SDimitry Andric         CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
3072bfef3995SDimitry Andric     assert(CorrespondingCallOpSpecialization);
3073bfef3995SDimitry Andric     CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
3074bfef3995SDimitry Andric   }
3075b1c73532SDimitry Andric 
3076b1c73532SDimitry Andric   // Special lambda forwarding when there are inalloca parameters.
3077b1c73532SDimitry Andric   if (hasInAllocaArg(MD)) {
3078b1c73532SDimitry Andric     const CGFunctionInfo *ImplFnInfo = nullptr;
3079b1c73532SDimitry Andric     llvm::Function *ImplFn = nullptr;
3080b1c73532SDimitry Andric     EmitLambdaInAllocaImplFn(CallOp, &ImplFnInfo, &ImplFn);
3081b1c73532SDimitry Andric 
3082b1c73532SDimitry Andric     EmitForwardingCallToLambda(CallOp, CallArgs, ImplFnInfo, ImplFn);
3083b1c73532SDimitry Andric     return;
3084b1c73532SDimitry Andric   }
3085b1c73532SDimitry Andric 
3086bfef3995SDimitry Andric   EmitForwardingCallToLambda(CallOp, CallArgs);
3087dbe13110SDimitry Andric }
3088dbe13110SDimitry Andric 
EmitLambdaInAllocaCallOpBody(const CXXMethodDecl * MD)3089b1c73532SDimitry Andric void CodeGenFunction::EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD) {
3090dbe13110SDimitry Andric   if (MD->isVariadic()) {
3091dbe13110SDimitry Andric     // FIXME: Making this work correctly is nasty because it requires either
3092dbe13110SDimitry Andric     // cloning the body of the call operator or making the call operator forward.
3093dbe13110SDimitry Andric     CGM.ErrorUnsupported(MD, "lambda conversion to variadic function");
3094dbe13110SDimitry Andric     return;
3095dbe13110SDimitry Andric   }
3096dbe13110SDimitry Andric 
3097b1c73532SDimitry Andric   // Forward %this argument.
3098b1c73532SDimitry Andric   CallArgList CallArgs;
3099b1c73532SDimitry Andric   QualType LambdaType = getContext().getRecordType(MD->getParent());
3100b1c73532SDimitry Andric   QualType ThisType = getContext().getPointerType(LambdaType);
3101b1c73532SDimitry Andric   llvm::Value *ThisArg = CurFn->getArg(0);
3102b1c73532SDimitry Andric   CallArgs.add(RValue::get(ThisArg), ThisType);
3103b1c73532SDimitry Andric 
3104b1c73532SDimitry Andric   EmitLambdaDelegatingInvokeBody(MD, CallArgs);
3105b1c73532SDimitry Andric }
3106b1c73532SDimitry Andric 
EmitLambdaInAllocaImplFn(const CXXMethodDecl * CallOp,const CGFunctionInfo ** ImplFnInfo,llvm::Function ** ImplFn)3107b1c73532SDimitry Andric void CodeGenFunction::EmitLambdaInAllocaImplFn(
3108b1c73532SDimitry Andric     const CXXMethodDecl *CallOp, const CGFunctionInfo **ImplFnInfo,
3109b1c73532SDimitry Andric     llvm::Function **ImplFn) {
3110b1c73532SDimitry Andric   const CGFunctionInfo &FnInfo =
3111b1c73532SDimitry Andric       CGM.getTypes().arrangeCXXMethodDeclaration(CallOp);
3112b1c73532SDimitry Andric   llvm::Function *CallOpFn =
3113b1c73532SDimitry Andric       cast<llvm::Function>(CGM.GetAddrOfFunction(GlobalDecl(CallOp)));
3114b1c73532SDimitry Andric 
3115b1c73532SDimitry Andric   // Emit function containing the original call op body. __invoke will delegate
3116b1c73532SDimitry Andric   // to this function.
3117b1c73532SDimitry Andric   SmallVector<CanQualType, 4> ArgTypes;
3118b1c73532SDimitry Andric   for (auto I = FnInfo.arg_begin(); I != FnInfo.arg_end(); ++I)
3119b1c73532SDimitry Andric     ArgTypes.push_back(I->type);
3120b1c73532SDimitry Andric   *ImplFnInfo = &CGM.getTypes().arrangeLLVMFunctionInfo(
3121b1c73532SDimitry Andric       FnInfo.getReturnType(), FnInfoOpts::IsDelegateCall, ArgTypes,
3122b1c73532SDimitry Andric       FnInfo.getExtInfo(), {}, FnInfo.getRequiredArgs());
3123b1c73532SDimitry Andric 
3124b1c73532SDimitry Andric   // Create mangled name as if this was a method named __impl. If for some
3125b1c73532SDimitry Andric   // reason the name doesn't look as expected then just tack __impl to the
3126b1c73532SDimitry Andric   // front.
3127b1c73532SDimitry Andric   // TODO: Use the name mangler to produce the right name instead of using
3128b1c73532SDimitry Andric   // string replacement.
3129b1c73532SDimitry Andric   StringRef CallOpName = CallOpFn->getName();
3130b1c73532SDimitry Andric   std::string ImplName;
3131b1c73532SDimitry Andric   if (size_t Pos = CallOpName.find_first_of("<lambda"))
3132b1c73532SDimitry Andric     ImplName = ("?__impl@" + CallOpName.drop_front(Pos)).str();
3133b1c73532SDimitry Andric   else
3134b1c73532SDimitry Andric     ImplName = ("__impl" + CallOpName).str();
3135b1c73532SDimitry Andric 
3136b1c73532SDimitry Andric   llvm::Function *Fn = CallOpFn->getParent()->getFunction(ImplName);
3137b1c73532SDimitry Andric   if (!Fn) {
3138b1c73532SDimitry Andric     Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(**ImplFnInfo),
3139b1c73532SDimitry Andric                                 llvm::GlobalValue::InternalLinkage, ImplName,
3140b1c73532SDimitry Andric                                 CGM.getModule());
3141b1c73532SDimitry Andric     CGM.SetInternalFunctionAttributes(CallOp, Fn, **ImplFnInfo);
3142b1c73532SDimitry Andric 
3143b1c73532SDimitry Andric     const GlobalDecl &GD = GlobalDecl(CallOp);
3144b1c73532SDimitry Andric     const auto *D = cast<FunctionDecl>(GD.getDecl());
3145b1c73532SDimitry Andric     CodeGenFunction(CGM).GenerateCode(GD, Fn, **ImplFnInfo);
3146b1c73532SDimitry Andric     CGM.SetLLVMFunctionAttributesForDefinition(D, Fn);
3147b1c73532SDimitry Andric   }
3148b1c73532SDimitry Andric   *ImplFn = Fn;
314929cafa66SDimitry Andric }
3150