29#include "llvm/IR/Intrinsics.h"
30#include "llvm/IR/Metadata.h"
31#include "llvm/Support/SaveAndRestore.h"
32#include "llvm/Transforms/Utils/SanitizerStats.h"
52 return layout.getNonVirtualAlignment();
84 CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment();
97 return std::min(actualBaseAlign, expectedTargetAlign);
100 CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment();
120 if (actualBaseAlign >= expectedBaseAlign) {
121 return expectedTargetAlign;
127 return std::min(actualBaseAlign, expectedTargetAlign);
131 assert(
CurFuncDecl &&
"loading 'this' without a func declaration?");
135 if (CXXThisAlignment.isZero()) {
139 CXXThisAlignment =
CGM.getClassPointerAlignment(MD->getParent());
143 LoadCXXThis(), MD->getFunctionObjectParameterType(), CXXThisAlignment,
151 const Expr *E,
Address base, llvm::Value *memberPtr,
155 llvm::Value *ptr =
CGM.getCXXABI().EmitMemberDataPointerAddress(
156 *
this, E, base, memberPtr, memberPtrType, IsInBounds);
160 CGM.getNaturalTypeAlignment(memberType, BaseInfo, TBAAInfo);
161 memberAlign =
CGM.getDynamicOffsetAlignment(
178 assert(!
Base->isVirtual() &&
"Should not see virtual bases here!");
183 const auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
196 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
206 return llvm::ConstantInt::get(
PtrDiffTy, Offset.getQuantity());
216 bool BaseIsVirtual) {
231 if (!Offset.isZero()) {
233 V =
Builder.CreateConstInBoundsByteGEP(
V, Offset);
240 llvm::Value *virtualOffset,
const CXXRecordDecl *derivedClass,
243 assert(!nonVirtualOffset.
isZero() || virtualOffset !=
nullptr);
246 llvm::Value *baseOffset;
247 if (!nonVirtualOffset.
isZero()) {
248 llvm::Type *OffsetType =
254 llvm::ConstantInt::get(OffsetType, nonVirtualOffset.
getQuantity());
256 baseOffset = CGF.
Builder.CreateAdd(virtualOffset, baseOffset);
259 baseOffset = virtualOffset;
270 assert(nearestVBase &&
"virtual offset without vbase?");
286 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
295 if ((*Start)->isVirtual()) {
296 VBase = (*Start)->getType()->castAsCXXRecordDecl();
303 CharUnits NonVirtualOffset =
CGM.computeNonVirtualBaseClassOffset(
304 VBase ? VBase : Derived, Start, PathEnd);
309 if (VBase && Derived->
hasAttr<FinalAttr>()) {
312 NonVirtualOffset += vBaseOffset;
318 llvm::Type *PtrTy = llvm::PointerType::get(
322 CharUnits DerivedAlign =
CGM.getClassPointerAlignment(Derived);
326 if (NonVirtualOffset.
isZero() && !VBase) {
329 SkippedChecks.
set(SanitizerKind::Null, !NullCheckValue);
331 DerivedAlign, SkippedChecks);
333 return Value.withElementType(BaseValueTy);
336 llvm::BasicBlock *origBB =
nullptr;
337 llvm::BasicBlock *endBB =
nullptr;
341 if (NullCheckValue) {
342 origBB =
Builder.GetInsertBlock();
347 Builder.CreateCondBr(isNull, endBB, notNullBB);
353 SkippedChecks.
set(SanitizerKind::Null,
true);
355 Value.emitRawPointer(*
this), DerivedTy, DerivedAlign,
360 llvm::Value *VirtualOffset =
nullptr;
363 CGM.getCXXABI().GetVirtualBaseClassOffset(*
this,
Value, Derived, VBase);
368 VirtualOffset, Derived, VBase);
374 if (NullCheckValue) {
375 llvm::BasicBlock *notNullBB =
Builder.GetInsertBlock();
379 llvm::PHINode *PHI =
Builder.CreatePHI(PtrTy, 2,
"cast.result");
380 PHI->addIncoming(
Value.emitRawPointer(*
this), notNullBB);
381 PHI->addIncoming(llvm::Constant::getNullValue(PtrTy), origBB);
392 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
395 llvm::Type *DerivedValueTy =
ConvertType(DerivedTy);
397 llvm::Value *NonVirtualOffset =
398 CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd);
400 if (!NonVirtualOffset) {
405 llvm::BasicBlock *CastNull =
nullptr;
406 llvm::BasicBlock *CastNotNull =
nullptr;
407 llvm::BasicBlock *CastEnd =
nullptr;
409 if (NullCheckValue) {
423 CGM.getClassPointerAlignment(Derived),
"sub.ptr");
426 Addr =
Addr.withElementType(DerivedValueTy);
429 if (NullCheckValue) {
435 llvm::Value *
Value =
Addr.emitRawPointer(*
this);
437 PHI->addIncoming(
Value, CastNotNull);
438 PHI->addIncoming(llvm::Constant::getNullValue(
Value->
getType()), CastNull);
440 CGM.getClassPointerAlignment(Derived));
449 if (!
CGM.getCXXABI().NeedsVTTParameter(GD)) {
457 uint64_t SubVTTIndex;
462 }
else if (RD ==
Base) {
465 assert(!
CGM.getCXXABI().NeedsVTTParameter(
CurGD) &&
466 "doing no-op VTT offset in base dtor/ctor?");
467 assert(!ForVirtualBase &&
"Can't have same class as virtual base!");
476 assert(SubVTTIndex != 0 &&
"Sub-VTT index must be greater than zero!");
480 if (
CGM.getCXXABI().NeedsVTTParameter(
CurGD)) {
485 VTT =
CGM.getVTables().GetAddrOfVTT(RD);
487 return Builder.CreateConstInBoundsGEP1_64(
CGM.GlobalsInt8PtrTy, VTT,
493struct CallBaseDtor final : EHScopeStack::Cleanup {
497 : BaseClass(
Base), BaseIsVirtual(BaseIsVirtual) {}
510 false,
Addr, ThisTy);
516struct DynamicThisUseChecker
517 : ConstEvaluatedExprVisitor<DynamicThisUseChecker> {
518 typedef ConstEvaluatedExprVisitor<DynamicThisUseChecker> super;
522 DynamicThisUseChecker(
const ASTContext &
C) : super(
C), UsesThis(
false) {}
529 void VisitCXXThisExpr(
const CXXThisExpr *E) { UsesThis =
true; }
534 DynamicThisUseChecker Checker(
C);
536 return Checker.UsesThis;
559 ThisPtr, ClassDecl, BaseClassDecl, isBaseVirtual);
568 !BaseClassDecl->hasTrivialDestructor())
580 for (
const auto *I : IndirectField->
chain())
595 "Must have member initializer!");
596 assert(MemberInit->
getInit() &&
"Must have initializer!");
600 QualType FieldType = Field->getType();
629 unsigned SrcArgIndex =
631 llvm::Value *SrcPtr =
639 LHS.isVolatileQualified());
654 QualType FieldType = Field->getType();
746 struct SizeAndOffset {
751 unsigned PtrSize =
CGM.getDataLayout().getPointerSizeInBits();
758 Context.toCharUnitsFromBits(Info.
getFieldOffset(i)).getQuantity();
760 size_t NumFields = 0;
761 for (
const auto *Field : ClassDecl->
fields()) {
763 auto FieldInfo = Context.getTypeInfoInChars(D->
getType());
765 assert(NumFields < SSV.size());
769 assert(NumFields == SSV.size());
776 llvm::FunctionType *FTy = llvm::FunctionType::get(
CGM.VoidTy, Args,
false);
777 llvm::FunctionCallee F =
CGM.CreateRuntimeFunction(
778 FTy, Prologue ?
"__asan_poison_intra_object_redzone"
779 :
"__asan_unpoison_intra_object_redzone");
786 for (
size_t i = 0; i < SSV.size(); i++) {
787 uint64_t AsanAlignment = 8;
788 uint64_t NextField = i == SSV.size() - 1 ? TypeSize : SSV[i + 1].Offset;
789 uint64_t PoisonSize = NextField - SSV[i].Offset - SSV[i].Size;
790 uint64_t EndOffset = SSV[i].Offset + SSV[i].Size;
791 if (PoisonSize < AsanAlignment || !SSV[i].Size ||
792 (NextField % AsanAlignment) != 0)
795 F, {
Builder.CreateAdd(ThisPtr,
Builder.getIntN(PtrSize, EndOffset)),
796 Builder.getIntN(PtrSize, PoisonSize)});
806 assert((
CGM.getTarget().getCXXABI().hasConstructorVariants() ||
808 "can only generate complete ctor for this ABI");
813 CGM.getTarget().getCXXABI().hasConstructorVariants()) {
820 assert(
Definition == Ctor &&
"emitting wrong constructor body");
824 bool IsTryBody = isa_and_nonnull<CXXTryStmt>(Body);
861class CopyingValueRepresentation {
864 : CGF(CGF), OldSanOpts(CGF.SanOpts) {
868 ~CopyingValueRepresentation() { CGF.
SanOpts = OldSanOpts; }
877class FieldMemcpyizer {
879 FieldMemcpyizer(CodeGenFunction &CGF,
const CXXRecordDecl *ClassDecl,
880 const VarDecl *SrcRec)
881 : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec),
882 RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)),
884 LastFieldOffset(0), LastAddedFieldIndex(0) {}
886 bool isMemcpyableField(FieldDecl *F)
const {
904 void addMemcpyableField(FieldDecl *F) {
913 CharUnits getMemcpySize(uint64_t FirstByteOffset)
const {
915 unsigned LastFieldSize =
916 LastField->isBitField()
917 ? LastField->getBitWidthValue()
920 uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize -
934 if (FirstField->isBitField()) {
935 const CGRecordLayout &RL =
942 FirstByteOffset = FirstFieldOffset;
945 CharUnits MemcpySize = getMemcpySize(FirstByteOffset);
954 emitMemcpyIR(Dest.isBitField() ? Dest.getBitFieldAddress()
956 Src.isBitField() ? Src.getBitFieldAddress() : Src.getAddress(),
961 void reset() { FirstField =
nullptr; }
964 CodeGenFunction &CGF;
965 const CXXRecordDecl *ClassDecl;
968 void emitMemcpyIR(Address DestPtr, Address SrcPtr, CharUnits Size) {
975 void addInitialField(FieldDecl *F) {
978 FirstFieldOffset = RecLayout.getFieldOffset(F->
getFieldIndex());
979 LastFieldOffset = FirstFieldOffset;
983 void addNextField(FieldDecl *F) {
989 "Cannot aggregate fields out of order.");
996 if (FOffset < FirstFieldOffset) {
998 FirstFieldOffset = FOffset;
999 }
else if (FOffset >= LastFieldOffset) {
1001 LastFieldOffset = FOffset;
1005 const VarDecl *SrcRec;
1006 const ASTRecordLayout &RecLayout;
1007 FieldDecl *FirstField;
1008 FieldDecl *LastField;
1009 uint64_t FirstFieldOffset, LastFieldOffset;
1010 unsigned LastAddedFieldIndex;
1013class ConstructorMemcpyizer :
public FieldMemcpyizer {
1017 static const VarDecl *getTrivialCopySource(CodeGenFunction &CGF,
1018 const CXXConstructorDecl *CD,
1019 FunctionArgList &Args) {
1027 bool isMemberInitMemcpyable(CXXCtorInitializer *MemberInit)
const {
1028 if (!MemcpyableCtor)
1031 assert(Field &&
"No field for member init.");
1032 QualType FieldType =
Field->getType();
1033 CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->
getInit());
1043 if (!isMemcpyableField(Field))
1051 ConstructorMemcpyizer(CodeGenFunction &CGF,
const CXXConstructorDecl *CD,
1052 FunctionArgList &Args)
1053 : FieldMemcpyizer(CGF, CD->getParent(),
1054 getTrivialCopySource(CGF, CD, Args)),
1055 ConstructorDecl(CD),
1056 MemcpyableCtor(CD->isDefaulted() && CD->isCopyOrMoveConstructor() &&
1057 CGF.getLangOpts().getGC() == LangOptions::NonGC),
1060 void addMemberInitializer(CXXCtorInitializer *MemberInit) {
1061 if (isMemberInitMemcpyable(MemberInit)) {
1062 AggregatedInits.push_back(MemberInit);
1063 addMemcpyableField(MemberInit->
getMember());
1065 emitAggregatedInits();
1067 ConstructorDecl, Args);
1071 void emitAggregatedInits() {
1072 if (AggregatedInits.size() <= 1) {
1075 if (!AggregatedInits.empty()) {
1076 CopyingValueRepresentation CVR(CGF);
1078 AggregatedInits[0], ConstructorDecl, Args);
1079 AggregatedInits.clear();
1085 pushEHDestructors();
1088 AggregatedInits.clear();
1091 void pushEHDestructors() {
1096 for (
unsigned i = 0; i < AggregatedInits.size(); ++i) {
1097 CXXCtorInitializer *MemberInit = AggregatedInits[i];
1102 LValue FieldLHS = LHS;
1104 CGF.
pushEHDestroy(dtorKind, FieldLHS.getAddress(), FieldType);
1108 void finish() { emitAggregatedInits(); }
1111 const CXXConstructorDecl *ConstructorDecl;
1112 bool MemcpyableCtor;
1113 FunctionArgList &Args;
1114 SmallVector<CXXCtorInitializer *, 16> AggregatedInits;
1117class AssignmentMemcpyizer :
public FieldMemcpyizer {
1121 FieldDecl *getMemcpyableField(Stmt *S) {
1122 if (!AssignmentsMemcpyable)
1124 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) {
1126 if (BO->getOpcode() != BO_Assign)
1128 MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS());
1132 if (!Field || !isMemcpyableField(Field))
1134 Stmt *RHS = BO->getRHS();
1135 if (ImplicitCastExpr *EC = dyn_cast<ImplicitCastExpr>(RHS))
1136 RHS = EC->getSubExpr();
1139 if (MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) {
1140 if (ME2->getMemberDecl() == Field)
1144 }
else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) {
1145 CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl());
1148 MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument());
1152 if (!Field || !isMemcpyableField(Field))
1154 MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0));
1155 if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->
getMemberDecl()))
1158 }
else if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
1159 FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
1160 if (!FD || FD->
getBuiltinID() != Builtin::BI__builtin_memcpy)
1162 Expr *DstPtr = CE->
getArg(0);
1163 if (ImplicitCastExpr *DC = dyn_cast<ImplicitCastExpr>(DstPtr))
1164 DstPtr = DC->getSubExpr();
1165 UnaryOperator *DUO = dyn_cast<UnaryOperator>(DstPtr);
1166 if (!DUO || DUO->
getOpcode() != UO_AddrOf)
1168 MemberExpr *ME = dyn_cast<MemberExpr>(DUO->
getSubExpr());
1172 if (!Field || !isMemcpyableField(Field))
1174 Expr *SrcPtr = CE->
getArg(1);
1175 if (ImplicitCastExpr *SC = dyn_cast<ImplicitCastExpr>(SrcPtr))
1176 SrcPtr = SC->getSubExpr();
1177 UnaryOperator *SUO = dyn_cast<UnaryOperator>(SrcPtr);
1178 if (!SUO || SUO->
getOpcode() != UO_AddrOf)
1180 MemberExpr *ME2 = dyn_cast<MemberExpr>(SUO->
getSubExpr());
1181 if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->
getMemberDecl()))
1189 bool AssignmentsMemcpyable;
1190 SmallVector<Stmt *, 16> AggregatedStmts;
1193 AssignmentMemcpyizer(CodeGenFunction &CGF,
const CXXMethodDecl *AD,
1194 FunctionArgList &Args)
1195 : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]),
1196 AssignmentsMemcpyable(CGF.getLangOpts().getGC() == LangOptions::NonGC) {
1197 assert(Args.size() == 2);
1200 void emitAssignment(Stmt *S) {
1201 FieldDecl *F = getMemcpyableField(S);
1203 addMemcpyableField(F);
1204 AggregatedStmts.push_back(S);
1206 emitAggregatedStmts();
1211 void emitAggregatedStmts() {
1212 if (AggregatedStmts.size() <= 1) {
1213 if (!AggregatedStmts.empty()) {
1214 CopyingValueRepresentation CVR(CGF);
1222 AggregatedStmts.clear();
1225 void finish() { emitAggregatedStmts(); }
1252 bool ConstructVBases = CtorType !=
Ctor_Base &&
1259 llvm::BasicBlock *BaseCtorContinueBB =
nullptr;
1260 if (ConstructVBases &&
1261 !
CGM.getTarget().getCXXABI().hasConstructorVariants()) {
1262 BaseCtorContinueBB =
1263 CGM.getCXXABI().EmitCtorCompleteObjectHandler(*
this, ClassDecl);
1264 assert(BaseCtorContinueBB);
1268 auto AllInits = CD->
inits();
1271 auto VirtualBaseEnd = std::find_if(
1273 return !(Init->isBaseInitializer() && Init->isBaseVirtual());
1276 auto NonVirtualBaseEnd = std::find_if(VirtualBaseEnd, AllInits.end(),
1278 return !Init->isBaseInitializer();
1282 auto VirtualBaseInits = llvm::make_range(AllInits.begin(), VirtualBaseEnd);
1283 auto NonVirtualBaseInits =
1284 llvm::make_range(VirtualBaseEnd, NonVirtualBaseEnd);
1285 auto MemberInits = llvm::make_range(NonVirtualBaseEnd, AllInits.end());
1288 if (ConstructVBases) {
1291 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
1292 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1299 if (BaseCtorContinueBB) {
1301 Builder.CreateBr(BaseCtorContinueBB);
1309 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
1310 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1320 ConstructorMemcpyizer CM(*
this, CD, Args);
1322 assert(!
Member->isBaseInitializer());
1323 assert(
Member->isAnyMemberInitializer() &&
1324 "Delegating initializer on non-delegating constructor");
1325 CM.addMemberInitializer(
Member);
1346 for (
const auto *Field : BaseClassDecl->
fields())
1351 for (
const auto &I : BaseClassDecl->
bases()) {
1357 MostDerivedClassDecl))
1361 if (BaseClassDecl == MostDerivedClassDecl) {
1363 for (
const auto &I : BaseClassDecl->
vbases()) {
1364 const auto *
VirtualBase = I.getType()->castAsCXXRecordDecl();
1375 QualType FieldBaseElementType = Context.getBaseElementType(Field->getType());
1378 if (!FieldClassDecl)
1382 if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
1405 for (
const auto *Field : ClassDecl->
fields())
1414 llvm::Value *ShouldDeleteCondition) {
1417 llvm::BasicBlock *callDeleteBB =
1421 llvm::Value *CheckTheBitForArrayDestroy = CGF.
Builder.CreateAnd(
1422 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 2));
1423 llvm::Value *ShouldDestroyArray =
1425 CGF.
Builder.CreateCondBr(ShouldDestroyArray, ScalarBB, VectorBB);
1429 llvm::Value *numElements =
nullptr;
1430 llvm::Value *allocatedPtr =
nullptr;
1434 allocatedPtr, cookieSize);
1440 assert(numElements &&
"no element count for a type with a destructor!");
1448 ThisPtr.
getElementType(), arrayBegin, numElements,
"delete.end");
1459 llvm::Value *CheckTheBitForDeleteCall = CGF.
Builder.CreateAnd(
1460 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 1));
1462 llvm::Value *ShouldCallDelete =
1473 numElements, cookieSize);
1478 llvm::Value *CheckTheBitForGlobDeleteCall = CGF.
Builder.CreateAnd(
1479 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4));
1481 llvm::Value *ShouldCallGlobDelete =
1483 llvm::BasicBlock *GlobDelete =
1485 llvm::BasicBlock *ClassDelete =
1487 CGF.
Builder.CreateCondBr(ShouldCallGlobDelete, ClassDelete, GlobDelete);
1491 numElements, cookieSize);
1497 numElements, cookieSize);
1501 llvm::CallInst *TrapCall = CGF.
EmitTrapCall(llvm::Intrinsic::trap);
1502 TrapCall->setDoesNotReturn();
1503 TrapCall->setDoesNotThrow();
1504 CGF.
Builder.CreateUnreachable();
1505 CGF.
Builder.ClearInsertionPoint();
1523 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
1524 TrapCall->setDoesNotReturn();
1525 TrapCall->setDoesNotThrow();
1527 Builder.ClearInsertionPoint();
1556 bool isTryBody = isa_and_nonnull<CXXTryStmt>(Body);
1571 llvm_unreachable(
"not expecting a unified dtor");
1573 llvm_unreachable(
"not expecting a COMDAT");
1575 llvm_unreachable(
"already handled deleting case");
1577 llvm_unreachable(
"already handled vector deleting case");
1580 assert((Body ||
getTarget().getCXXABI().isMicrosoft()) &&
1581 "can't emit a dtor without a body for non-Microsoft ABIs");
1606 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
1607 CGM.getCodeGenOpts().OptimizationLevel > 0)
1617 assert(Dtor->
isImplicit() &&
"bodyless dtor not implicit");
1623 CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
1641 "Body of an implicit assignment operator should be compound stmt.");
1648 AssignmentMemcpyizer AM(*
this, AssignOp, Args);
1649 for (
auto *I : RootCS->
body())
1650 AM.emitAssignment(I);
1664struct CallDtorDelete final : EHScopeStack::Cleanup {
1671 LoadThisForDtorDelete(CGF, Dtor),
1682 llvm::Value *ShouldDeleteCondition,
1683 bool ReturnAfterDelete) {
1685 const CXXRecordDecl *ClassDecl = Dtor->
getParent();
1688 "unexpected value for ReturnAfterDelete");
1703 llvm::Value *Check3rdBit = CGF.
Builder.CreateAnd(
1704 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4));
1706 CGF.
Builder.CreateCondBr(ShouldCallDtor, DontCallDtor, CallDtor);
1712 CGF.
Builder.CreateBr(DontCallDtor);
1718 llvm::Value *Check1stBit = CGF.
Builder.CreateAnd(
1719 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 1));
1721 CGF.
Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
1724 auto EmitDeleteAndGoToEnd = [&](
const FunctionDecl *DeleteOp) {
1727 if (ReturnAfterDelete)
1730 CGF.
Builder.CreateBr(continueBB);
1739 llvm::Value *CheckTheBitForGlobDeleteCall = CGF.
Builder.CreateAnd(
1740 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4));
1741 llvm::Value *ShouldCallGlobDelete =
1743 llvm::BasicBlock *GlobDelete =
1745 llvm::BasicBlock *ClassDelete =
1747 CGF.
Builder.CreateCondBr(ShouldCallGlobDelete, ClassDelete, GlobDelete);
1750 EmitDeleteAndGoToEnd(GlobOD);
1753 EmitDeleteAndGoToEnd(OD);
1757struct CallDtorDeleteConditional final : EHScopeStack::Cleanup {
1758 llvm::Value *ShouldDeleteCondition;
1761 CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition)
1762 : ShouldDeleteCondition(ShouldDeleteCondition) {
1763 assert(ShouldDeleteCondition !=
nullptr);
1766 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1767 EmitConditionalDtorDeleteCall(CGF, ShouldDeleteCondition,
1772class DestroyField final :
public EHScopeStack::Cleanup {
1773 const FieldDecl *field;
1775 bool useEHCleanupForArray;
1779 bool useEHCleanupForArray)
1780 : field(field), destroyer(destroyer),
1781 useEHCleanupForArray(useEHCleanupForArray) {}
1783 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1790 assert(LV.isSimple());
1792 CGF.
emitDestroy(LV.getAddress(), field->getType(), destroyer,
1793 flags.isForNormalCleanup() && useEHCleanupForArray);
1797class DeclAsInlineDebugLocation {
1799 llvm::MDNode *InlinedAt;
1800 std::optional<ApplyDebugLocation> Location;
1803 DeclAsInlineDebugLocation(CodeGenFunction &CGF,
const NamedDecl &
Decl)
1804 : DI(CGF.getDebugInfo()) {
1809 Location.emplace(CGF,
Decl.getLocation());
1812 ~DeclAsInlineDebugLocation() {
1820static void EmitSanitizerDtorCallback(
1822 std::optional<CharUnits::QuantityType> PoisonSize = {}) {
1826 SmallVector<llvm::Value *, 2> Args = {Ptr};
1827 SmallVector<llvm::Type *, 2> ArgTypes = {CGF.
VoidPtrTy};
1829 if (PoisonSize.has_value()) {
1830 Args.emplace_back(llvm::ConstantInt::get(CGF.
SizeTy, *PoisonSize));
1831 ArgTypes.emplace_back(CGF.
SizeTy);
1834 llvm::FunctionType *FnType =
1835 llvm::FunctionType::get(CGF.
VoidTy, ArgTypes,
false);
1842EmitSanitizerDtorFieldsCallback(
CodeGenFunction &CGF, llvm::Value *Ptr,
1844 EmitSanitizerDtorCallback(CGF,
"__sanitizer_dtor_callback_fields", Ptr,
1849struct SanitizeDtorTrivialBase final : EHScopeStack::Cleanup {
1850 const CXXRecordDecl *BaseClass;
1852 SanitizeDtorTrivialBase(
const CXXRecordDecl *Base,
bool BaseIsVirtual)
1853 : BaseClass(
Base), BaseIsVirtual(BaseIsVirtual) {}
1855 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1856 const CXXRecordDecl *DerivedClass =
1862 const ASTRecordLayout &BaseLayout =
1864 CharUnits BaseSize = BaseLayout.
getSize();
1871 DeclAsInlineDebugLocation InlineHere(CGF, *BaseClass);
1872 EmitSanitizerDtorFieldsCallback(CGF,
Addr.emitRawPointer(CGF),
1876 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1880class SanitizeDtorFieldRange final :
public EHScopeStack::Cleanup {
1881 const CXXDestructorDecl *Dtor;
1882 unsigned StartIndex;
1886 SanitizeDtorFieldRange(
const CXXDestructorDecl *Dtor,
unsigned StartIndex,
1888 : Dtor(Dtor), StartIndex(StartIndex), EndIndex(EndIndex) {}
1893 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1894 const ASTContext &Context = CGF.
getContext();
1895 const ASTRecordLayout &Layout =
1902 llvm::ConstantInt *OffsetSizePtr =
1905 llvm::Value *OffsetPtr =
1908 CharUnits PoisonEnd;
1914 CharUnits PoisonSize = PoisonEnd - PoisonStart;
1919 DeclAsInlineDebugLocation InlineHere(
1920 CGF, **std::next(Dtor->getParent()->field_begin(), StartIndex));
1921 EmitSanitizerDtorFieldsCallback(CGF, OffsetPtr, PoisonSize.
getQuantity());
1924 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1928class SanitizeDtorVTable final :
public EHScopeStack::Cleanup {
1929 const CXXDestructorDecl *Dtor;
1932 SanitizeDtorVTable(
const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
1935 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1936 assert(Dtor->getParent()->isDynamicClass());
1943 EmitSanitizerDtorCallback(CGF,
"__sanitizer_dtor_callback_vptr", VTablePtr);
1947class SanitizeDtorCleanupBuilder {
1948 ASTContext &Context;
1949 EHScopeStack &EHStack;
1950 const CXXDestructorDecl *DD;
1951 std::optional<unsigned> StartIndex;
1954 SanitizeDtorCleanupBuilder(ASTContext &Context, EHScopeStack &EHStack,
1955 const CXXDestructorDecl *DD)
1956 : Context(Context), EHStack(EHStack), DD(DD), StartIndex(std::nullopt) {}
1957 void PushCleanupForField(
const FieldDecl *Field) {
1960 unsigned FieldIndex =
Field->getFieldIndex();
1963 StartIndex = FieldIndex;
1964 }
else if (StartIndex) {
1966 *StartIndex, FieldIndex);
1967 StartIndex = std::nullopt;
1987 "Should not emit dtor epilogue for non-exported trivial dtor!");
1993 "operator delete missing - EnterDtorCleanups");
1994 if (CXXStructorImplicitParamValue) {
1998 EmitConditionalDtorDeleteCall(*
this, CXXStructorImplicitParamValue,
2001 EHStack.pushCleanup<CallDtorDeleteConditional>(
2007 LoadThisForDtorDelete(*
this, DD),
2008 getContext().getCanonicalTagType(ClassDecl));
2027 if (
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
2034 for (
const auto &
Base : ClassDecl->
vbases()) {
2035 auto *BaseClassDecl =
Base.getType()->castAsCXXRecordDecl();
2036 if (BaseClassDecl->hasTrivialDestructor()) {
2040 if (
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
2041 SanOpts.has(SanitizerKind::Memory) && !BaseClassDecl->isEmpty())
2057 if (
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
2063 for (
const auto &
Base : ClassDecl->
bases()) {
2065 if (
Base.isVirtual())
2071 if (
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
2084 bool SanitizeFields =
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
2085 SanOpts.has(SanitizerKind::Memory);
2089 for (
const auto *Field : ClassDecl->
fields()) {
2091 SanitizeBuilder.PushCleanupForField(Field);
2099 const RecordType *RT =
type->getAsUnionType();
2100 if (RT && RT->getDecl()->isAnonymousStructOrUnion())
2104 EHStack.pushCleanup<DestroyField>(
2109 SanitizeBuilder.End();
2124 bool NewPointerIsChecked,
2125 bool zeroInitialize) {
2127 llvm::Value *numElements =
2131 NewPointerIsChecked, zeroInitialize);
2145 const CXXConstructExpr *E,
bool NewPointerIsChecked,
bool zeroInitialize) {
2151 llvm::CondBrInst *zeroCheckBranch =
nullptr;
2154 llvm::ConstantInt *constantCount = dyn_cast<llvm::ConstantInt>(numElements);
2155 if (constantCount) {
2157 if (constantCount->isZero())
2163 llvm::Value *iszero =
Builder.CreateIsNull(numElements,
"isempty");
2164 zeroCheckBranch =
Builder.CreateCondBr(iszero, loopBB, loopBB);
2171 llvm::Value *arrayEnd =
Builder.CreateInBoundsGEP(
2172 elementType, arrayBegin, numElements,
"arrayctor.end");
2175 llvm::BasicBlock *entryBB =
Builder.GetInsertBlock();
2178 llvm::PHINode *cur =
2179 Builder.CreatePHI(arrayBegin->getType(), 2,
"arrayctor.cur");
2180 cur->addIncoming(arrayBegin, entryBB);
2183 if (
CGM.shouldEmitConvergenceTokens())
2231 llvm::Value *next =
Builder.CreateInBoundsGEP(
2232 elementType, cur, llvm::ConstantInt::get(
SizeTy, 1),
"arrayctor.next");
2233 cur->addIncoming(next,
Builder.GetInsertBlock());
2236 llvm::Value *done =
Builder.CreateICmpEQ(next, arrayEnd,
"arrayctor.done");
2238 Builder.CreateCondBr(done, contBB, loopBB);
2241 if (zeroCheckBranch)
2242 zeroCheckBranch->setSuccessor(0, contBB);
2244 if (
CGM.shouldEmitConvergenceTokens())
2265 llvm::Value *ThisPtr =
2268 if (SlotAS != ThisAS) {
2270 llvm::Type *NewType =
2282 assert(E->
getNumArgs() == 1 &&
"unexpected argcount for trivial ctor");
2333 bool NewPointerIsChecked, llvm::CallBase **CallOrInvoke) {
2336 if (!NewPointerIsChecked)
2342 assert(Args.size() == 1 &&
"trivial default ctor with args");
2350 assert(Args.size() == 2 &&
"unexpected argcount for trivial ctor");
2353 Args[1].getRValue(*this).getScalarVal(), SrcTy);
2361 bool PassPrototypeArgs =
true;
2374 CGM.getCXXABI().addImplicitConstructorArgs(*
this, D,
Type, ForVirtualBase,
2396 if (
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2398 CGM.getCXXABI().canSpeculativelyEmitVTable(ClassDecl) &&
2399 CGM.getCodeGenOpts().StrictVTablePointers)
2412 if (InheritedFromVBase &&
2413 CGM.getTarget().getCXXABI().hasConstructorVariants()) {
2418 Args.push_back(ThisArg);
2419 }
else if (!CXXInheritedCtorInitExprArgs.empty()) {
2421 assert(CXXInheritedCtorInitExprArgs.size() >= D->
getNumParams() &&
2422 "wrong number of parameters for inherited constructor call");
2423 Args = CXXInheritedCtorInitExprArgs;
2427 Args.push_back(ThisArg);
2429 assert(OuterCtor->getNumParams() == D->
getNumParams());
2430 assert(!OuterCtor->isVariadic() &&
"should have been inlined");
2432 for (
const auto *Param : OuterCtor->parameters()) {
2434 OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->getType(),
2439 if (Param->hasAttr<PassObjectSizeAttr>()) {
2440 auto *POSParam = SizeArguments[Param];
2441 assert(POSParam &&
"missing pass_object_size value for forwarding");
2461 CXXInheritedCtorInitExprArgs = Args;
2468 CGM.getCXXABI().addImplicitConstructorArgs(*
this, Ctor, CtorType,
2472 assert(Args.size() >= Params.size() &&
"too few arguments for call");
2473 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
2475 const RValue &RV = Args[I].getRValue(*
this);
2476 assert(!RV.
isComplex() &&
"complex indirect params not supported");
2490 CGM.getCXXABI().EmitInstanceFunctionProlog(*
this);
2491 CXXThisValue = CXXABIThisValue;
2498 llvm::Value *VTableGlobal =
2506 if (!NonVirtualOffset.
isZero())
2511 llvm::Value *VPtrValue =
2514 Builder.CreateICmpEQ(VPtrValue, VTableGlobal,
"cmp.vtables");
2520 if (
CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl))
2538 llvm::Type *t =
CGM.getTypes().ConvertType(QT);
2540 llvm::Value *SrcVal =
Builder.CreateBitCast(Val, t);
2558 FunctionArgList::const_iterator I = Args.begin(), E = Args.end();
2559 assert(I != E &&
"no parameters to constructor");
2564 This, (*I)->getType()->getPointeeType())),
2570 if (
CGM.getCXXABI().NeedsVTTParameter(
CurGD)) {
2571 assert(I != E &&
"cannot skip vtt parameter, already done with args");
2572 assert((*I)->getType()->isPointerType() &&
2573 "skipping parameter not of vtt type");
2578 for (; I != E; ++I) {
2585 true,
This, DelegateArgs,
2591struct CallDelegatingCtorDtor final : EHScopeStack::Cleanup {
2603 QualType ThisTy = Dtor->getFunctionObjectParameterType();
2605 true,
Addr, ThisTy);
2630 EHStack.pushCleanup<CallDelegatingCtorDtor>(
2637 bool ForVirtualBase,
2640 CGM.getCXXABI().EmitDestructorCall(*
this, DD,
Type, ForVirtualBase,
2645struct CallLocalDtor final : EHScopeStack::Cleanup {
2674 assert(D && D->
isUsed() &&
"destructor not marked as used!");
2680 llvm::Value *VTableAddressPoint =
2681 CGM.getCXXABI().getVTableAddressPointInStructor(
2684 if (!VTableAddressPoint)
2688 llvm::Value *VirtualOffset =
nullptr;
2691 if (
CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*
this, Vptr)) {
2695 VirtualOffset =
CGM.getCXXABI().GetVirtualBaseClassOffset(
2705 if (!NonVirtualOffset.
isZero() || VirtualOffset)
2707 *
this, VTableField, NonVirtualOffset, VirtualOffset, Vptr.
VTableClass,
2712 unsigned GlobalsAS =
CGM.getDataLayout().getDefaultGlobalsAddressSpace();
2713 llvm::Type *PtrTy = llvm::PointerType::get(
CGM.getLLVMContext(), GlobalsAS);
2718 if (
auto AuthenticationInfo =
CGM.getVTablePointerAuthInfo(
2720 VTableAddressPoint =
2723 llvm::StoreInst *Store =
Builder.CreateStore(VTableAddressPoint, VTableField);
2725 CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
2726 if (
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2727 CGM.getCodeGenOpts().StrictVTablePointers)
2728 CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.
VTableClass);
2738 false, VTableClass, VBases,
2746 bool BaseIsNonVirtualPrimaryBase,
2752 if (!BaseIsNonVirtualPrimaryBase) {
2754 VPtr Vptr = {
Base, NearestVBase, OffsetFromNearestVBase, VTableClass};
2755 Vptrs.push_back(Vptr);
2761 for (
const auto &I : RD->
bases()) {
2762 auto *BaseDecl = I.getType()->castAsCXXRecordDecl();
2764 if (!BaseDecl->isDynamicClass())
2769 bool BaseDeclIsNonVirtualPrimaryBase;
2771 if (I.isVirtual()) {
2773 if (!VBases.insert(BaseDecl).second)
2781 BaseDeclIsNonVirtualPrimaryBase =
false;
2786 BaseOffsetFromNearestVBase =
2788 BaseDeclIsNonVirtualPrimaryBase = Layout.
getPrimaryBase() == BaseDecl;
2793 I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase,
2794 BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs);
2804 if (
CGM.getCXXABI().doStructorsInitializeVPtrs(RD))
2809 CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*
this, RD);
2815 Address VTablePtrSrc =
This.withElementType(VTableTy);
2816 llvm::Instruction *VTable =
Builder.CreateLoad(VTablePtrSrc,
"vtable");
2818 CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo);
2820 if (
auto AuthenticationInfo =
2821 CGM.getVTablePointerAuthInfo(
this, RD,
This.emitRawPointer(*
this))) {
2842 if (
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2843 CGM.getCodeGenOpts().StrictVTablePointers)
2844 CGM.DecorateInstructionWithInvariantGroup(VTable, RD);
2885 llvm::Value *VTable,
2887 if (
SanOpts.has(SanitizerKind::CFIVCall))
2895 else if ((
CGM.getCodeGenOpts().WholeProgramVTables &&
2896 !
CGM.AlwaysHasLTOVisibilityPublic(RD)) ||
2897 CGM.getCodeGenOpts().DevirtualizeSpeculatively) {
2899 llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(Ty);
2900 llvm::Value *TypeId = llvm::MetadataAsValue::get(
CGM.getLLVMContext(), MD);
2906 llvm::Intrinsic::ID IID =
CGM.HasHiddenLTOVisibility(RD)
2907 ? llvm::Intrinsic::type_test
2908 : llvm::Intrinsic::public_type_test;
2909 llvm::Value *TypeTest =
2910 Builder.CreateCall(
CGM.getIntrinsic(IID), {VTable, TypeId});
2911 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest);
2917static std::pair<SanitizerKind::SanitizerOrdinal, llvm::SanitizerStatKind>
2921 return std::make_pair(SanitizerKind::SO_CFIVCall, llvm::SanStat_CFI_VCall);
2923 return std::make_pair(SanitizerKind::SO_CFINVCall,
2924 llvm::SanStat_CFI_NVCall);
2926 return std::make_pair(SanitizerKind::SO_CFIDerivedCast,
2927 llvm::SanStat_CFI_DerivedCast);
2929 return std::make_pair(SanitizerKind::SO_CFIUnrelatedCast,
2930 llvm::SanStat_CFI_UnrelatedCast);
2934 llvm_unreachable(
"unexpected sanitizer kind");
2936 llvm_unreachable(
"Unknown CFITypeCheckKind enum");
2940 llvm::Value *VTable,
2943 if (!
SanOpts.has(SanitizerKind::CFICastStrict))
2948 SanitizerHandler::CFICheckFail);
2960 const auto *ClassDecl = T->getAsCXXRecordDecl();
2967 if (!
SanOpts.has(SanitizerKind::CFICastStrict))
2972 SanitizerHandler::CFICheckFail);
2974 llvm::BasicBlock *ContBlock =
nullptr;
2977 llvm::Value *DerivedNotNull =
2983 Builder.CreateCondBr(DerivedNotNull, CheckBlock, ContBlock);
2988 llvm::Value *VTable;
2989 std::tie(VTable, ClassDecl) =
2990 CGM.getCXXABI().LoadVTablePtr(*
this, Derived, ClassDecl);
3001 llvm::Value *VTable,
3006 if (!
CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
3007 !
CGM.HasHiddenLTOVisibility(RD))
3013 if (
getContext().getNoSanitizeList().containsType(
3020 llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(T);
3021 llvm::Value *TypeId = llvm::MetadataAsValue::get(
getLLVMContext(), MD);
3023 llvm::Value *TypeTest =
Builder.CreateCall(
3024 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, TypeId});
3026 llvm::Constant *StaticData[] = {
3027 llvm::ConstantInt::get(
Int8Ty, TCK),
3032 auto CrossDsoTypeId =
CGM.CreateCrossDsoCfiTypeId(MD);
3033 if (
CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) {
3038 if (
CGM.getCodeGenOpts().SanitizeTrap.has(M)) {
3039 bool NoMerge = !
CGM.getCodeGenOpts().SanitizeMergeHandlers.has(M);
3040 EmitTrapCheck(TypeTest, SanitizerHandler::CFICheckFail, NoMerge);
3044 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
3045 CGM.getLLVMContext(),
3046 llvm::MDString::get(
CGM.getLLVMContext(),
"all-vtables"));
3047 llvm::Value *ValidVtable =
Builder.CreateCall(
3048 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
3049 EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail,
3050 StaticData, {VTable, ValidVtable});
3054 if ((!
CGM.getCodeGenOpts().WholeProgramVTables ||
3055 !
CGM.HasHiddenLTOVisibility(RD)) &&
3056 !
CGM.getCodeGenOpts().DevirtualizeSpeculatively)
3059 if (
CGM.getCodeGenOpts().VirtualFunctionElimination)
3062 if (!
SanOpts.has(SanitizerKind::CFIVCall) ||
3063 !
CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIVCall))
3072 const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy,
3073 uint64_t VTableByteOffset) {
3074 auto CheckOrdinal = SanitizerKind::SO_CFIVCall;
3075 auto CheckHandler = SanitizerHandler::CFICheckFail;
3081 llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(T);
3082 llvm::Value *TypeId = llvm::MetadataAsValue::get(
CGM.getLLVMContext(), MD);
3084 auto CheckedLoadIntrinsic =
CGM.getLangOpts().RelativeCXXABIVTables
3085 ? llvm::Intrinsic::type_checked_load_relative
3086 : llvm::Intrinsic::type_checked_load;
3087 llvm::Value *CheckedLoad =
Builder.CreateCall(
3088 CGM.getIntrinsic(CheckedLoadIntrinsic),
3089 {VTable, llvm::ConstantInt::get(Int32Ty, VTableByteOffset), TypeId});
3091 llvm::Value *CheckResult =
Builder.CreateExtractValue(CheckedLoad, 1);
3094 if (
SanOpts.has(SanitizerKind::CFIVCall) &&
3095 !
getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall,
3097 EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler, {}, {});
3100 return Builder.CreateBitCast(
Builder.CreateExtractValue(CheckedLoad, 0),
3109 calleeFnInfo = &
CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
3114 CGM.getTypes().GetFunctionType(*calleeFnInfo));
3121 if (!resultType->isVoidType() &&
3134 RValue RV =
EmitCall(*calleeFnInfo, callee, returnSlot, callArgs);
3137 if (!resultType->isVoidType() && returnSlot.
isNull()) {
3138 if (
getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType()) {
3141 EmitReturnOfRValue(RV, resultType);
3152 if (CallOp->isVariadic()) {
3156 CGM.ErrorUnsupported(
CurCodeDecl,
"lambda conversion to variadic function");
3173 "generic lambda interconversion to block not implemented");
3182 CGM.ErrorUnsupported(MD,
"lambda conversion to variadic function");
3213 CallOp->getDescribedFunctionTemplate();
3214 void *InsertPos =
nullptr;
3217 assert(CorrespondingCallOpSpecialization);
3222 if (hasInAllocaArg(MD)) {
3224 llvm::Function *ImplFn =
nullptr;
3239 CGM.ErrorUnsupported(MD,
"lambda conversion to variadic function");
3247 llvm::Value *ThisArg =
CurFn->getArg(0);
3255 llvm::Function **ImplFn) {
3257 CGM.getTypes().arrangeCXXMethodDeclaration(CallOp);
3258 llvm::Function *CallOpFn =
3265 ArgTypes.push_back(I->type);
3266 *ImplFnInfo = &
CGM.getTypes().arrangeLLVMFunctionInfo(
3275 StringRef CallOpName = CallOpFn->getName();
3276 std::string ImplName;
3277 if (
size_t Pos = CallOpName.find_first_of(
"<lambda"))
3278 ImplName = (
"?__impl@" + CallOpName.drop_front(Pos)).str();
3280 ImplName = (
"__impl" + CallOpName).str();
3282 llvm::Function *Fn = CallOpFn->getParent()->getFunction(ImplName);
3284 Fn = llvm::Function::Create(
CGM.getTypes().GetFunctionType(**ImplFnInfo),
3285 llvm::GlobalValue::InternalLinkage, ImplName,
3287 CGM.SetInternalFunctionAttributes(CallOp, Fn, **ImplFnInfo);
3291 CodeGenFunction(
CGM).GenerateCode(GD, Fn, **ImplFnInfo);
3292 CGM.SetLLVMFunctionAttributesForDefinition(D, Fn);
static Address ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, CharUnits nonVirtualOffset, llvm::Value *virtualOffset, const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase)
static bool canEmitDelegateCallArgs(CodeGenFunction &CGF, const CXXConstructorDecl *Ctor, CXXCtorType Type, CallArgList &Args)
static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor)
CanSkipVTablePointerInitialization - Check whether we need to initialize any vtable pointers before c...
static const CXXRecordDecl * LeastDerivedClassWithSameLayout(const CXXRecordDecl *RD)
static void EmitBaseInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *BaseInit)
static std::pair< SanitizerKind::SanitizerOrdinal, llvm::SanitizerStatKind > SanitizerInfoFromCFICheckKind(CodeGenFunction::CFITypeCheckKind TCK)
Converts the CFITypeCheckKind into SanitizerKind::SanitizerOrdinal and llvm::SanitizerStatKind.
static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init)
static bool FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field)
static void EmitConditionalArrayDtorCall(const CXXDestructorDecl *DD, CodeGenFunction &CGF, llvm::Value *ShouldDeleteCondition)
static bool HasTrivialDestructorBody(ASTContext &Context, const CXXRecordDecl *BaseClassDecl, const CXXRecordDecl *MostDerivedClassDecl)
static void EmitMemberInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *MemberInit, const CXXConstructorDecl *Constructor, FunctionArgList &Args)
static void EmitLValueForAnyFieldInitialization(CodeGenFunction &CGF, CXXCtorInitializer *MemberInit, LValue &LHS)
static bool isInitializerOfDynamicClass(const CXXCtorInitializer *baseInit)
Defines the C++ template declaration subclasses.
a trap message and trap category.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
bool isPFPField(const FieldDecl *Field) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const NoSanitizeList & getNoSanitizeList() const
bool arePFPFieldsTriviallyCopyable(const RecordDecl *RD) const
Returns whether this record's PFP fields (if any) are trivially copyable (i.e.
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
unsigned getTargetAddressSpace(LangAS AS) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
CharUnits getSize() const
getSize - Get the record size in characters.
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
capture_const_iterator capture_begin() const
ArrayRef< ParmVarDecl * > parameters() const
Represents a base class of a C++ class.
QualType getType() const
Retrieves the type of the base class.
Represents a call to a C++ constructor.
Expr * getArg(unsigned Arg)
Return the specified argument.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
init_iterator init_begin()
Retrieve an iterator to the first initializer.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
Represents a C++ base or member initializer.
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
Expr * getInit() const
Get the initializer.
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
bool isAnyMemberInitializer() const
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
bool isIndirectMemberInitializer() const
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
FieldDecl * getAnyMember() const
IndirectFieldDecl * getIndirectMember() const
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Represents a C++ destructor within a class.
const FunctionDecl * getOperatorGlobalDelete() const
const FunctionDecl * getGlobalArrayOperatorDelete() const
const FunctionDecl * getOperatorDelete() const
Expr * getOperatorDeleteThisArg() const
const FunctionDecl * getArrayOperatorDelete() const
Represents a call to an inherited base class constructor from an inheriting constructor.
SourceLocation getLocation() const LLVM_READONLY
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
QualType getFunctionObjectParameterType() const
bool isMemcpyEquivalentSpecialMember(const ASTContext &Ctx) const
Returns whether this is a copy/move constructor or assignment operator that can be implemented as a m...
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
method_range methods() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
base_class_range vbases()
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
const CXXBaseSpecifier *const * path_const_iterator
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
bool isSanitizerChecked() const
Address getAddress() const
Qualifiers getQualifiers() const
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
Overlap_t mayOverlap() const
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
A scoped helper to set the current debug location to the specified location or preferred location of ...
A scoped helper to set the current debug location to an inlined location.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &Args) const =0
virtual void ReadArrayCookie(CodeGenFunction &CGF, Address Ptr, const CXXDeleteExpr *expr, QualType ElementType, llvm::Value *&NumElements, llvm::Value *&AllocPtr, CharUnits &CookieSize)
Reads the array cookie associated with the given pointer, if it has one.
All available information about a concrete callee.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
llvm::MDNode * getInlinedAt() const
void setInlinedAt(llvm::MDNode *InlinedAt)
Update the current inline scope.
CGFunctionInfo - Class to encapsulate the information about a function definition.
bool usesInAlloca() const
Return true if this function uses inalloca arguments.
FunctionType::ExtInfo getExtInfo() const
ABIArgInfo & getReturnInfo()
const_arg_iterator arg_begin() const
CanQualType getReturnType() const
const_arg_iterator arg_end() const
RequiredArgs getRequiredArgs() const
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
A scope within which we are constructing the fields of an object which might use a CXXDefaultInitExpr...
static ParamValue forIndirect(Address addr)
static ParamValue forDirect(llvm::Value *value)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void ForceCleanup(std::initializer_list< llvm::Value ** > ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void emitArrayDestroy(llvm::Value *begin, llvm::Value *end, QualType elementType, CharUnits elementAlign, Destroyer *destroyer, bool checkZeroLength, bool useEHCleanup)
emitArrayDestroy - Destroys all the elements of the given array, beginning from last to first.
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass, VTableAuthMode AuthMode=VTableAuthMode::Authenticate)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, const FunctionArgList &Args)
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
emitDestroy - Immediately perform the destruction of the given object.
AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD)
Determine whether a field initialization may overlap some other object.
void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, CXXCtorType CtorType, const FunctionArgList &Args, SourceLocation Loc)
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitAsanPrologueOrEpilogue(bool Prologue)
void EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase, bool Delegating, CallArgList &Args)
Emit a call to an inheriting constructor (that is, one that invokes a constructor inherited from a ba...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
Address LoadCXXThisAddress()
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK)
void pushEHDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushEHDestroy - Push the standard destructor for the given type as an EH-only cleanup.
void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD)
void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD, CallArgList &CallArgs)
Address GetAddressOfBaseClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue, SourceLocation Loc)
GetAddressOfBaseClass - This function will add the necessary delta to the load of 'this' and returns ...
LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T)
Given a value of type T* that may not be to a complete object, construct an l-value with the natural ...
void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
pushRegularPartialArrayCleanup - Push an EH cleanup to destroy already-constructed elements of the gi...
SmallVector< llvm::ConvergenceControlInst *, 4 > ConvergenceTokenStack
Stack to track the controlled convergence tokens.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator, CallArgList &CallArgs, const CGFunctionInfo *CallOpFnInfo=nullptr, llvm::Constant *CallOpFn=nullptr)
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
See CGDebugInfo::addInstToCurrentSourceAtom.
AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *RD, const CXXRecordDecl *BaseRD, bool IsVirtual)
Determine whether a base class initialization may overlap some other object.
const LangOptions & getLangOpts() const
llvm::Value * EmitARCRetainAutoreleasedReturnValue(llvm::Value *value)
Retain the given object which is the result of a function call.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor)
Checks whether the given constructor is a valid subject for the complete-to-base constructor delegati...
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheck - Emit a check that VTable is a valid virtual table for RD using llvm....
void EmitConstructorBody(FunctionArgList &Args)
EmitConstructorBody - Emits the body of the current constructor.
const CodeGen::CGBlockInfo * BlockInfo
void EmitAggregateCopyCtor(LValue Dest, LValue Src, AggValueSlot::Overlap_t MayOverlap)
Address makeNaturalAddressForPointer(llvm::Value *Ptr, QualType T, CharUnits Alignment=CharUnits::Zero(), bool ForPointeeType=false, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
Construct an address with the natural alignment of T.
static Destroyer destroyCXXObject
void EmitLambdaInAllocaImplFn(const CXXMethodDecl *CallOp, const CGFunctionInfo **ImplFnInfo, llvm::Function **ImplFn)
void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, const ArrayType *ArrayTy, Address ArrayPtr, const CXXConstructExpr *E, bool NewPointerIsChecked, bool ZeroInitialization=false)
EmitCXXAggrConstructorCall - Emit a loop to call a particular constructor for each of several members...
VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass)
void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
@ TCK_ConstructorCall
Checking the 'this' pointer for a constructor call.
@ TCK_UpcastToVirtualBase
Checking the operand of a cast to a virtual base object.
@ TCK_Upcast
Checking the operand of a cast to a base object.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
void PushDestructorCleanup(QualType T, Address Addr)
PushDestructorCleanup - Push a cleanup to call the complete-object destructor of an object of the giv...
JumpDest ReturnBlock
ReturnBlock - Unified return block.
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
@ ForceLeftToRight
! Language semantics require left-to-right evaluation.
@ Default
! No language constraints on evaluation order.
llvm::SmallPtrSet< const CXXRecordDecl *, 4 > VisitedVirtualBasesSetTy
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field, bool IsInBounds=true)
const TargetInfo & getTarget() const
Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base, llvm::Value *memberPtr, const MemberPointerType *memberPtrType, bool IsInBounds, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Emit the address of a field using a member data pointer.
void maybeCreateMCDCCondBitmap()
Allocate a temp value on the stack that MCDC can use to track condition results.
Address GetAddrOfBlockDecl(const VarDecl *var)
RawAddress CreateIRTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateIRTempWithoutCast - Create a temporary IR object of the given type, with appropriate alignment.
void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type)
EnterDtorCleanups - Enter the cleanups necessary to complete the given phase of destruction for a des...
llvm::Value * EmitPointerAuthSign(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, AggValueSlot ThisAVS, const CXXConstructExpr *E)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)
emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This)
Emit assumption load for all bases.
CGDebugInfo * getDebugInfo()
void EmitDestructorBody(FunctionArgList &Args)
EmitDestructorBody - Emits the body of the current destructor.
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference,...
Address GetAddressOfDirectBaseInCompleteClass(Address Value, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, bool BaseIsVirtual)
GetAddressOfBaseOfCompleteClass - Convert the given pointer to a complete class to the given direct b...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type, FunctionArgList &Args)
EmitCtorPrologue - This routine generates necessary code to initialize base classes and non-static da...
void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)
If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases.
void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo)
EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init)
void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD)
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
CleanupKind getCleanupKind(QualType::DestructionKind kind)
llvm::Type * ConvertTypeForMem(QualType T)
void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, Address This, Address Src, const CXXConstructExpr *E)
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void emitImplicitAssignmentOperatorBody(FunctionArgList &Args)
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
void EmitLambdaBlockInvokeBody()
void EmitCfiSlowPathCheck(SanitizerKind::SanitizerOrdinal Ordinal, llvm::Value *Cond, llvm::ConstantInt *TypeId, llvm::Value *Ptr, ArrayRef< llvm::Constant * > StaticArgs)
Emit a slow path cross-DSO CFI check which calls __cfi_slowpath if Cond if false.
void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D, bool ForVirtualBase, Address This, bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E)
Emit a call to a constructor inherited from a base class, passing the current constructor's arguments...
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Value * GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating)
GetVTTParameter - Return the VTT parameter that should be passed to a base constructor/destructor wit...
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
EmitCallArgs - Emit call arguments for a function.
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)
Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void InitializeVTablePointer(const VPtr &vptr)
Initialize the vtable pointer of the given subobject.
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
llvm::LLVMContext & getLLVMContext()
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::SmallVector< VPtr, 4 > VPtrsVector
void InitializeVTablePointers(const CXXRecordDecl *ClassDecl)
void EmitVTableAssumptionLoad(const VPtr &vptr, Address This)
Emit assumption that vptr load == global vtable.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
llvm::Value * EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CharUnits getMinimumClassObjectSize(const CXXRecordDecl *CD)
Returns the minimum object size for an object of the given class type (or a class derived from it).
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Constant * GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd)
Returns the offset from a derived class to a class.
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
CGCXXABI & getCXXABI() const
CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the assumed alignment of a virtual base of a class.
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign, const CXXRecordDecl *Class, CharUnits ExpectedTargetAlign)
Given a class pointer with an actual known alignment, and the expected alignment of an object at a dy...
ASTContext & getContext() const
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
bool inheritingCtorHasParams(const InheritedConstructor &Inherited, CXXCtorType Type)
Determine if a C++ inheriting constructor should have parameters matching those of its inherited cons...
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, bool PassProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
Address getAddress() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
An abstract representation of an aligned address.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
CompoundStmt - This represents a group of statements like { stmt stmt }.
Represents the canonical version of C arrays with a specified constant size.
SourceLocation getEndLoc() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool hasTrivialBody() const
Returns whether the function has a trivial body that does not require any specific codegen.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isDefaulted() const
Whether this function is defaulted.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
param_type_iterator param_type_begin() const
bool isVariadic() const
Whether this function prototype is variadic.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
const Decl * getDecl() const
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
std::string getQualifiedNameAsString() const
bool containsType(SanitizerMask Mask, StringRef MangledTypeName, StringRef Category=StringRef()) const
bool isAddressDiscriminated() const
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PointerAuthQualifier getPointerAuth() const
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
The collection of all-type qualifiers we support.
bool hasObjCLifetime() const
LangAS getAddressSpace() const
field_range fields() const
bool mayInsertExtraPadding(bool EmitRemark=false) const
Whether we are allowed to insert extra padding between fields.
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
bool areArgsDestroyedLeftToRightInCallee() const
Are arguments to a call destroyed left to right in the callee?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
virtual bool callGlobalDeleteInDeletingDtor(const LangOptions &) const
Controls whether global operator delete is called by the deleting destructor or at the point where de...
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
CXXRecordDecl * castAsCXXRecordDecl() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Expr * getSubExpr() const
Represents a variable declaration or definition.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD)
isEmptyFieldForLayout - Return true iff the field is "empty", that is, either a zero-width bit-field ...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
@ Address
A pointer to a ValueDecl.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
CXXDtorType
C++ destructor types.
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
U cast(CodeGen::Address addr)
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
Similar to AddedStructorArgs, but only notes the number of additional arguments.
llvm::BasicBlock * getBlock() const
Struct with all information about dynamic [sub]class needed to set vptr.
const CXXRecordDecl * NearestVBase
const CXXRecordDecl * VTableClass
CharUnits OffsetFromNearestVBase
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::PointerType * Int8PtrTy
llvm::IntegerType * PtrDiffTy
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.