27 #include "llvm/IR/Intrinsics.h"
28 #include "llvm/IR/Metadata.h"
29 #include "llvm/Transforms/Utils/SanitizerStats.h"
31 using namespace clang;
32 using namespace CodeGen;
44 if (RD->hasAttr<FinalAttr>()) {
49 return layout.getNonVirtualAlignment();
63 CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment();
76 return std::min(actualBaseAlign, expectedTargetAlign);
79 CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment();
99 if (actualBaseAlign >= expectedBaseAlign) {
100 return expectedTargetAlign;
106 return std::min(actualBaseAlign, expectedTargetAlign);
110 assert(
CurFuncDecl &&
"loading 'this' without a func declaration?");
114 if (CXXThisAlignment.
isZero()) {
118 auto RD = cast<CXXMethodDecl>(
CurFuncDecl)->getParent();
136 memberPtr, memberPtrType);
144 return Address(ptr, memberAlign);
157 assert(!Base->
isVirtual() &&
"Should not see virtual bases here!");
166 Offset += Layout.getBaseClassOffset(BaseDecl);
178 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
188 return llvm::ConstantInt::get(PtrDiffTy, Offset.
getQuantity());
200 bool BaseIsVirtual) {
215 if (!Offset.isZero()) {
231 assert(!nonVirtualOffset.
isZero() || virtualOffset !=
nullptr);
235 if (!nonVirtualOffset.
isZero()) {
236 baseOffset = llvm::ConstantInt::get(CGF.
PtrDiffTy,
239 baseOffset = CGF.
Builder.CreateAdd(virtualOffset, baseOffset);
242 baseOffset = virtualOffset;
248 ptr = CGF.
Builder.CreateInBoundsGEP(ptr, baseOffset,
"add.ptr");
254 assert(nearestVBase &&
"virtual offset without vbase?");
256 derivedClass, nearestVBase);
262 return Address(ptr, alignment);
270 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
279 if ((*Start)->isVirtual()) {
281 cast<CXXRecordDecl>((*Start)->getType()->getAs<
RecordType>()->getDecl());
289 VBase ? VBase : Derived, Start, PathEnd);
294 if (VBase && Derived->hasAttr<FinalAttr>()) {
297 NonVirtualOffset += vBaseOffset;
303 ConvertType((PathEnd[-1])->getType())->getPointerTo();
310 if (NonVirtualOffset.
isZero() && !VBase) {
313 DerivedTy, DerivedAlign, !NullCheckValue);
318 llvm::BasicBlock *origBB =
nullptr;
319 llvm::BasicBlock *endBB =
nullptr;
323 if (NullCheckValue) {
324 origBB =
Builder.GetInsertBlock();
329 Builder.CreateCondBr(isNull, endBB, notNullBB);
335 Value.
getPointer(), DerivedTy, DerivedAlign,
true);
347 VirtualOffset, Derived, VBase);
353 if (NullCheckValue) {
354 llvm::BasicBlock *notNullBB =
Builder.GetInsertBlock();
358 llvm::PHINode *PHI =
Builder.CreatePHI(BasePtrTy, 2,
"cast.result");
359 PHI->addIncoming(Value.
getPointer(), notNullBB);
360 PHI->addIncoming(llvm::Constant::getNullValue(BasePtrTy), origBB);
372 bool NullCheckValue) {
373 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
382 if (!NonVirtualOffset) {
387 llvm::BasicBlock *CastNull =
nullptr;
388 llvm::BasicBlock *CastNotNull =
nullptr;
389 llvm::BasicBlock *CastEnd =
nullptr;
391 if (NullCheckValue) {
397 Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
403 Value =
Builder.CreateGEP(Value,
Builder.CreateNeg(NonVirtualOffset),
410 if (NullCheckValue) {
416 llvm::PHINode *PHI =
Builder.CreatePHI(Value->getType(), 2);
417 PHI->addIncoming(Value, CastNotNull);
418 PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull);
438 uint64_t SubVTTIndex;
443 }
else if (RD == Base) {
447 "doing no-op VTT offset in base dtor/ctor?");
448 assert(!ForVirtualBase &&
"Can't have same class as virtual base!");
458 assert(SubVTTIndex != 0 &&
"Sub-VTT index must be greater than zero!");
464 VTT =
Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
468 VTT =
Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex);
480 : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {}
489 DerivedClass, BaseClass,
503 DynamicThisUseChecker(
const ASTContext &C) : super(C), UsesThis(
false) {}
510 void VisitCXXThisExpr(
const CXXThisExpr *
E) { UsesThis =
true; }
515 DynamicThisUseChecker Checker(C);
517 return Checker.UsesThis;
525 "Must have base initializer!");
536 if (CtorType ==
Ctor_Base && isBaseVirtual)
572 if (Index == ArrayIndexes.size()) {
580 Dest = CGF.
Builder.CreateInBoundsGEP(Dest, ArrayIndex,
"destaddress");
582 Next = CGF.
Builder.CreateAdd(ArrayIndex, Next,
"inc");
614 assert(Array &&
"Array initialization without the array type?");
631 uint64_t NumElements = Array->
getSize().getZExtValue();
634 llvm::ConstantInt::get(Counter->getType(), NumElements);
639 CGF.
Builder.CreateCondBr(IsLess, ForBody, AfterFor);
652 llvm::Value *NextVal = llvm::ConstantInt::get(Counter->getType(), 1);
654 NextVal = CGF.
Builder.CreateAdd(Counter, NextVal,
"inc");
666 if (!(CD && CD->isCopyOrMoveConstructor()) &&
688 for (
const auto *
I : IndirectField->
chain())
702 "Must have member initializer!");
703 assert(MemberInit->
getInit() &&
"Must have initializer!");
707 QualType FieldType = Field->getType();
728 unsigned SrcArgIndex =
770 if (ArrayIndexes.size()) {
775 BasePtr = llvm::PointerType::getUnqual(BasePtr);
787 for (
unsigned I = 0, N = ArrayIndexes.size();
I != N; ++
I)
857 Prologue ? cast<CXXConstructorDecl>(
CurGD.
getDecl())->getParent()
858 : cast<CXXDestructorDecl>(
CurGD.
getDecl())->getParent();
861 struct SizeAndOffset {
875 size_t NumFields = 0;
876 for (
const auto *Field : ClassDecl->
fields()) {
878 std::pair<CharUnits, CharUnits> FieldInfo =
881 assert(NumFields < SSV.size());
885 assert(NumFields == SSV.size());
886 if (SSV.size() <= 1)
return;
891 llvm::FunctionType *FTy =
892 llvm::FunctionType::get(
CGM.
VoidTy, Args,
false);
894 FTy, Prologue ?
"__asan_poison_intra_object_redzone"
895 :
"__asan_unpoison_intra_object_redzone");
902 for (
size_t i = 0; i < SSV.size(); i++) {
903 uint64_t AsanAlignment = 8;
904 uint64_t NextField = i == SSV.size() - 1 ? TypeSize : SSV[i + 1].Offset;
905 uint64_t PoisonSize = NextField - SSV[i].Offset - SSV[i].Size;
906 uint64_t EndOffset = SSV[i].Offset + SSV[i].Size;
907 if (PoisonSize < AsanAlignment || !SSV[i].Size ||
908 (NextField % AsanAlignment) != 0)
911 F, {
Builder.CreateAdd(ThisPtr,
Builder.getIntN(PtrSize, EndOffset)),
912 Builder.getIntN(PtrSize, PoisonSize)});
924 "can only generate complete ctor for this ABI");
936 assert(Definition == Ctor &&
"emitting wrong constructor body");
940 bool IsTryBody = (Body && isa<CXXTryStmt>(Body));
957 EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
976 class CopyingValueRepresentation {
979 : CGF(CGF), OldSanOpts(CGF.SanOpts) {
983 ~CopyingValueRepresentation() {
993 class FieldMemcpyizer {
997 : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec),
998 RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)),
999 FirstField(nullptr), LastField(nullptr), FirstFieldOffset(0),
1000 LastFieldOffset(0), LastAddedFieldIndex(0) {}
1002 bool isMemcpyableField(
FieldDecl *F)
const {
1019 CharUnits getMemcpySize(uint64_t FirstByteOffset)
const {
1020 unsigned LastFieldSize =
1021 LastField->isBitField() ?
1022 LastField->getBitWidthValue(CGF.
getContext()) :
1024 uint64_t MemcpySizeBits =
1025 LastFieldOffset + LastFieldSize - FirstByteOffset +
1039 uint64_t FirstByteOffset;
1040 if (FirstField->isBitField()) {
1048 FirstByteOffset = FirstFieldOffset;
1051 CharUnits MemcpySize = getMemcpySize(FirstByteOffset);
1067 FirstField =
nullptr;
1076 llvm::PointerType *DPT = DestPtr.
getType();
1078 llvm::Type::getInt8PtrTy(CGF.
getLLVMContext(), DPT->getAddressSpace());
1081 llvm::PointerType *SPT = SrcPtr.
getType();
1083 llvm::Type::getInt8PtrTy(CGF.
getLLVMContext(), SPT->getAddressSpace());
1092 FirstFieldOffset = RecLayout.getFieldOffset(F->
getFieldIndex());
1093 LastFieldOffset = FirstFieldOffset;
1103 "Cannot aggregate fields out of order.");
1109 uint64_t FOffset = RecLayout.getFieldOffset(F->
getFieldIndex());
1110 if (FOffset < FirstFieldOffset) {
1112 FirstFieldOffset = FOffset;
1113 }
else if (FOffset > LastFieldOffset) {
1115 LastFieldOffset = FOffset;
1123 uint64_t FirstFieldOffset, LastFieldOffset;
1124 unsigned LastAddedFieldIndex;
1127 class ConstructorMemcpyizer :
public FieldMemcpyizer {
1142 if (!MemcpyableCtor)
1145 assert(Field &&
"No field for member init.");
1156 if (!isMemcpyableField(Field))
1166 : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CGF, CD, Args)),
1167 ConstructorDecl(CD),
1168 MemcpyableCtor(CD->isDefaulted() &&
1169 CD->isCopyOrMoveConstructor() &&
1174 if (isMemberInitMemcpyable(MemberInit)) {
1175 AggregatedInits.push_back(MemberInit);
1176 addMemcpyableField(MemberInit->
getMember());
1178 emitAggregatedInits();
1180 ConstructorDecl, Args);
1184 void emitAggregatedInits() {
1185 if (AggregatedInits.size() <= 1) {
1188 if (!AggregatedInits.empty()) {
1189 CopyingValueRepresentation CVR(CGF);
1191 AggregatedInits[0], ConstructorDecl, Args);
1192 AggregatedInits.clear();
1198 pushEHDestructors();
1200 AggregatedInits.clear();
1203 void pushEHDestructors() {
1208 for (
unsigned i = 0; i < AggregatedInits.size(); ++i) {
1221 emitAggregatedInits();
1226 bool MemcpyableCtor;
1231 class AssignmentMemcpyizer :
public FieldMemcpyizer {
1236 if (!AssignmentsMemcpyable)
1240 if (BO->getOpcode() != BO_Assign)
1246 if (!Field || !isMemcpyableField(Field))
1248 Stmt *RHS = BO->getRHS();
1250 RHS = EC->getSubExpr();
1265 if (!Field || !isMemcpyableField(Field))
1268 if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->
getMemberDecl()))
1271 }
else if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
1273 if (!FD || FD->
getBuiltinID() != Builtin::BI__builtin_memcpy)
1277 DstPtr = DC->getSubExpr();
1279 if (!DUO || DUO->
getOpcode() != UO_AddrOf)
1285 if (!Field || !isMemcpyableField(Field))
1289 SrcPtr = SC->getSubExpr();
1291 if (!SUO || SUO->
getOpcode() != UO_AddrOf)
1294 if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->
getMemberDecl()))
1302 bool AssignmentsMemcpyable;
1308 : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]),
1309 AssignmentsMemcpyable(CGF.getLangOpts().getGC() ==
LangOptions::NonGC) {
1310 assert(Args.size() == 2);
1313 void emitAssignment(
Stmt *S) {
1316 addMemcpyableField(F);
1317 AggregatedStmts.push_back(S);
1319 emitAggregatedStmts();
1324 void emitAggregatedStmts() {
1325 if (AggregatedStmts.size() <= 1) {
1326 if (!AggregatedStmts.empty()) {
1327 CopyingValueRepresentation CVR(CGF);
1334 AggregatedStmts.clear();
1338 emitAggregatedStmts();
1345 const auto *BaseClassDecl =
1347 return BaseClassDecl->isDynamicClass();
1363 llvm::BasicBlock *BaseCtorContinueBB =
nullptr;
1368 BaseCtorContinueBB =
1370 assert(BaseCtorContinueBB);
1375 for (; B !=
E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
1383 if (BaseCtorContinueBB) {
1385 Builder.CreateBr(BaseCtorContinueBB);
1390 for (; B !=
E && (*B)->isBaseInitializer(); B++) {
1391 assert(!(*B)->isBaseVirtual());
1400 CXXThisValue = OldThis;
1406 ConstructorMemcpyizer CM(*
this, CD, Args);
1407 for (; B !=
E; B++) {
1411 "Delegating initializer on non-delegating constructor");
1412 CM.addMemberInitializer(Member);
1433 for (
const auto *Field : BaseClassDecl->
fields())
1438 for (
const auto &
I : BaseClassDecl->
bases()) {
1443 cast<CXXRecordDecl>(
I.getType()->castAs<
RecordType>()->getDecl());
1445 MostDerivedClassDecl))
1449 if (BaseClassDecl == MostDerivedClassDecl) {
1451 for (
const auto &
I : BaseClassDecl->
vbases()) {
1453 cast<CXXRecordDecl>(
I.getType()->castAs<
RecordType>()->getDecl());
1455 MostDerivedClassDecl))
1494 for (
const auto *Field : ClassDecl->
fields())
1524 bool isTryBody = (Body && isa<CXXTryStmt>(Body));
1539 llvm_unreachable(
"not expecting a COMDAT");
1541 case Dtor_Deleting: llvm_unreachable(
"already handled deleting case");
1544 assert((Body ||
getTarget().getCXXABI().isMicrosoft()) &&
1545 "can't emit a dtor without a body for non-Microsoft ABIs");
1574 EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
1578 assert(Dtor->isImplicit() &&
"bodyless dtor not implicit");
1584 CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
1600 assert(isa<CompoundStmt>(RootS) &&
1601 "Body of an implicit assignment operator should be compound stmt.");
1602 const CompoundStmt *RootCS = cast<CompoundStmt>(RootS);
1607 AssignmentMemcpyizer AM(*
this, AssignOp, Args);
1608 for (
auto *
I : RootCS->
body())
1609 AM.emitAssignment(
I);
1630 CallDtorDeleteConditional(
llvm::Value *ShouldDeleteCondition)
1631 : ShouldDeleteCondition(ShouldDeleteCondition) {
1632 assert(ShouldDeleteCondition !=
nullptr);
1639 = CGF.
Builder.CreateIsNull(ShouldDeleteCondition);
1640 CGF.
Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
1647 CGF.
Builder.CreateBr(continueBB);
1656 bool useEHCleanupForArray;
1660 bool useEHCleanupForArray)
1661 : field(field), destroyer(destroyer),
1662 useEHCleanupForArray(useEHCleanupForArray) {}
1673 flags.isForNormalCleanup() && useEHCleanupForArray);
1682 llvm::ConstantInt::get(CGF.
SizeTy, PoisonSize)};
1686 llvm::FunctionType *FnType =
1687 llvm::FunctionType::get(CGF.
VoidTy, ArgTypes,
false);
1711 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1716 unsigned fieldIndex = 0;
1717 int startIndex = -1;
1724 startIndex = fieldIndex;
1731 }
else if (startIndex >= 0) {
1733 PoisonMembers(CGF, startIndex, fieldIndex);
1747 unsigned layoutEndOffset) {
1752 llvm::ConstantInt *OffsetSizePtr = llvm::ConstantInt::get(
1774 if (PoisonSize == 0)
1777 EmitSanitizerDtorCallback(CGF, OffsetPtr, PoisonSize);
1799 EmitSanitizerDtorCallback(CGF, VTablePtr, PoisonSize);
1809 assert((!DD->
isTrivial() || DD->hasAttr<DLLExportAttr>()) &&
1810 "Should not emit dtor epilogue for non-exported trivial dtor!");
1816 "operator delete missing - EnterDtorCleanups");
1817 if (CXXStructorImplicitParamValue) {
1820 EHStack.pushCleanup<CallDtorDeleteConditional>(
1845 for (
const auto &
Base : ClassDecl->
vbases()) {
1847 = cast<CXXRecordDecl>(
Base.getType()->getAs<
RecordType>()->getDecl());
1870 for (
const auto &
Base : ClassDecl->
bases()) {
1872 if (
Base.isVirtual())
1893 for (
const auto *Field : ClassDecl->
fields()) {
1896 if (!dtorKind)
continue;
1903 EHStack.pushCleanup<DestroyField>(cleanupKind, Field,
1940 bool zeroInitialize) {
1946 llvm::BranchInst *zeroCheckBranch =
nullptr;
1949 llvm::ConstantInt *constantCount
1950 = dyn_cast<llvm::ConstantInt>(numElements);
1951 if (constantCount) {
1953 if (constantCount->isZero())
return;
1959 zeroCheckBranch =
Builder.CreateCondBr(iszero, loopBB, loopBB);
1969 llvm::BasicBlock *entryBB =
Builder.GetInsertBlock();
1972 llvm::PHINode *cur =
Builder.CreatePHI(arrayBegin->getType(), 2,
1974 cur->addIncoming(arrayBegin, entryBB);
2020 Builder.CreateInBoundsGEP(cur, llvm::ConstantInt::get(
SizeTy, 1),
2022 cur->addIncoming(next,
Builder.GetInsertBlock());
2027 Builder.CreateCondBr(done, contBB, loopBB);
2030 if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB);
2041 assert(!dtor->isTrivial());
2048 bool ForVirtualBase,
2049 bool Delegating,
Address This,
2060 assert(E->
getNumArgs() == 1 &&
"unexpected argcount for trivial ctor");
2087 if (
P->getType().isDestructedType())
2103 bool ForVirtualBase,
2117 assert(Args.size() == 1 &&
"trivial default ctor with args");
2125 assert(Args.size() == 2 &&
"unexpected argcount for trivial ctor");
2146 *
this, D, Type, ForVirtualBase, Delegating, Args);
2180 if (InheritedFromVBase &&
2186 Args.push_back(ThisArg);
2187 }
else if (!CXXInheritedCtorInitExprArgs.empty()) {
2189 assert(CXXInheritedCtorInitExprArgs.size() >= D->
getNumParams() &&
2190 "wrong number of parameters for inherited constructor call");
2191 Args = CXXInheritedCtorInitExprArgs;
2195 Args.push_back(ThisArg);
2196 const auto *OuterCtor = cast<CXXConstructorDecl>(
CurCodeDecl);
2197 assert(OuterCtor->getNumParams() == D->
getNumParams());
2198 assert(!OuterCtor->isVariadic() &&
"should have been inlined");
2200 for (
const auto *Param : OuterCtor->parameters()) {
2202 OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->getType(),
2207 if (Param->hasAttr<PassObjectSizeAttr>()) {
2208 auto *POSParam = SizeArguments[Param];
2209 assert(POSParam &&
"missing pass_object_size value for forwarding");
2225 CXXInheritedCtorInitExprArgs = Args;
2233 ForVirtualBase, Delegating, Args);
2236 assert(Args.size() >= Params.size() &&
"too few arguments for call");
2237 for (
unsigned I = 0, N = Args.size();
I != N; ++
I) {
2238 if (
I < Params.size() && isa<ImplicitParamDecl>(Params[
I])) {
2239 const RValue &RV = Args[
I].RV;
2240 assert(!RV.
isComplex() &&
"complex indirect params not supported");
2255 CXXThisValue = CXXABIThisValue;
2270 if (!NonVirtualOffset.
isZero())
2278 Builder.CreateICmpEQ(VPtrValue, VTableGlobal,
"cmp.vtables");
2279 Builder.CreateAssumption(Cmp);
2320 FunctionArgList::const_iterator
I = Args.begin(),
E = Args.end();
2321 assert(I !=
E &&
"no parameters to constructor");
2331 assert(I !=
E &&
"cannot skip vtt parameter, already done with args");
2332 assert((*I)->getType()->isPointerType() &&
2333 "skipping parameter not of vtt type");
2338 for (; I !=
E; ++
I) {
2345 true, This, DelegateArgs);
2356 : Dtor(D), Addr(Addr), Type(Type) {}
2381 if (
CGM.
getLangOpts().Exceptions && !ClassDecl->hasTrivialDestructor()) {
2386 ClassDecl->getDestructor(),
2393 bool ForVirtualBase,
2406 : Dtor(D), Addr(Addr) {}
2423 if (!ClassDecl)
return;
2427 assert(D && D->isUsed() &&
"destructor not marked as used!");
2437 if (!VTableAddressPoint)
2459 if (!NonVirtualOffset.
isZero() || VirtualOffset)
2461 *
this, VTableField, NonVirtualOffset, VirtualOffset, Vptr.
VTableClass,
2487 false, VTableClass, VBases,
2495 bool BaseIsNonVirtualPrimaryBase,
2501 if (!BaseIsNonVirtualPrimaryBase) {
2503 VPtr Vptr = {
Base, NearestVBase, OffsetFromNearestVBase, VTableClass};
2504 Vptrs.push_back(Vptr);
2510 for (
const auto &
I : RD->
bases()) {
2512 = cast<CXXRecordDecl>(
I.getType()->getAs<
RecordType>()->getDecl());
2520 bool BaseDeclIsNonVirtualPrimaryBase;
2522 if (
I.isVirtual()) {
2524 if (!VBases.insert(BaseDecl).second)
2532 BaseDeclIsNonVirtualPrimaryBase =
false;
2537 BaseOffsetFromNearestVBase =
2539 BaseDeclIsNonVirtualPrimaryBase = Layout.
getPrimaryBase() == BaseDecl;
2544 I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase,
2545 BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs);
2602 if (isa<CXXDestructorDecl>(MD) && MD->isImplicit())
2617 llvm::Metadata *MD =
2625 {CastedVTable, TypeId});
2637 if (!
SanOpts.
has(SanitizerKind::CFICastStrict))
2655 const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassTy->getDecl());
2660 if (!
SanOpts.
has(SanitizerKind::CFICastStrict))
2663 llvm::BasicBlock *ContBlock =
nullptr;
2667 Builder.CreateIsNotNull(Derived,
"cast.nonnull");
2672 Builder.CreateCondBr(DerivedNotNull, CheckBlock, ContBlock);
2697 if (
getContext().getSanitizerBlacklist().isBlacklistedType(TypeName))
2701 llvm::SanitizerStatKind SSK;
2704 SSK = llvm::SanStat_CFI_VCall;
2707 SSK = llvm::SanStat_CFI_NVCall;
2710 SSK = llvm::SanStat_CFI_DerivedCast;
2713 SSK = llvm::SanStat_CFI_UnrelatedCast;
2716 llvm_unreachable(
"not expecting CFITCK_ICall");
2720 llvm::Metadata *MD =
2726 CGM.
getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, TypeId});
2731 M = SanitizerKind::CFIVCall;
2734 M = SanitizerKind::CFINVCall;
2737 M = SanitizerKind::CFIDerivedCast;
2740 M = SanitizerKind::CFIUnrelatedCast;
2743 llvm_unreachable(
"not expecting CFITCK_ICall");
2746 llvm::Constant *StaticData[] = {
2747 llvm::ConstantInt::get(
Int8Ty, TCK),
2763 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
2767 CGM.
getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, AllVtables});
2768 EmitCheck(std::make_pair(TypeTest, M),
"cfi_check_fail", StaticData,
2769 {CastedVTable, ValidVtable});
2789 llvm::Metadata *MD =
2796 {CastedVTable, llvm::ConstantInt::get(
Int32Ty, VTableByteOffset),
2800 EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIVCall),
2801 "cfi_check_fail",
nullptr,
nullptr);
2804 Builder.CreateExtractValue(CheckedLoad, 0),
2805 cast<llvm::PointerType>(VTable->getType())->getElementType());
2812 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
2813 E = PE->getSubExpr();
2817 if (
const CastExpr *CE = dyn_cast<CastExpr>(E)) {
2818 if (CE->getCastKind() == CK_NoOp) {
2819 E = CE->getSubExpr();
2824 if (UO->getOpcode() == UO_Extension) {
2825 E = UO->getSubExpr();
2852 if (MostDerivedClassDecl->hasAttr<FinalAttr>())
2857 if (MD->hasAttr<FinalAttr>())
2862 if (MD->
getParent()->hasAttr<FinalAttr>())
2866 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Base)) {
2867 if (
const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
2869 return VD->getType()->isRecordType();
2878 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(Base))
2880 return VD->getType()->isRecordType();
2883 if (isa<CXXConstructExpr>(Base))
2887 if (isa<CXXBindTemporaryExpr>(Base))
2891 if (
const CallExpr *CE = dyn_cast<CallExpr>(Base))
2892 return CE->getCallReturnType(
getContext())->isRecordType();
2913 if (!resultType->isVoidType() &&
2924 callArgs, callOperator);
2927 if (!resultType->isVoidType() && returnSlot.
isNull())
2928 EmitReturnOfRValue(RV, resultType);
2950 "generic lambda interconversion to block not implemented");
2955 if (cast<CXXMethodDecl>(
CurCodeDecl)->isVariadic()) {
2986 void *InsertPos =
nullptr;
2989 assert(CorrespondingCallOpSpecialization);
2990 CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init, ArrayRef< VarDecl * > ArrayIndexes)
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
ReturnValueSlot - Contains the address where the return value of a function can be stored...
void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type)
EnterDtorCleanups - Enter the cleanups necessary to complete the given phase of destruction for a des...
unsigned getNumArrayIndices() const
Determine the number of implicit array indices used while described an array member initialization...
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, const FunctionDecl *CalleeDecl=nullptr, unsigned ParamsToSkip=0)
EmitCallArgs - Emit call arguments for a function.
void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, CXXCtorType CtorType, const FunctionArgList &Args, SourceLocation Loc)
void DecorateInstructionWithInvariantGroup(llvm::Instruction *I, const CXXRecordDecl *RD)
Adds !invariant.barrier !tag to instruction.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
A (possibly-)qualified type.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type, FunctionArgList &Args)
EmitCtorPrologue - This routine generates necessary code to initialize base classes and non-static da...
llvm::Value * getPointer() const
CodeGenTypes & getTypes()
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
CanQualType getReturnType() const
bool isBitField() const
Determines whether this field is a bitfield.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
QualType getType() const
Retrieves the type of the base class.
CXXCtorType getCtorType() const
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler...
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
AlignmentSource
The source of the alignment of an l-value; an expression of confidence in the alignment actually matc...
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
llvm::LLVMContext & getLLVMContext()
method_range methods() const
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
const TargetInfo & getTarget() const
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...
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
Checking the 'this' pointer for a constructor call.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Address getAddress() const
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Defines the C++ template declaration subclasses.
ParenExpr - This represents a parethesized expression, e.g.
void EmitAutoVarDecl(const VarDecl &D)
EmitAutoVarDecl - Emit an auto variable declaration.
const llvm::DataLayout & getDataLayout() const
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
static bool isMemcpyEquivalentSpecialMember(const CXXMethodDecl *D)
QualType getPointeeType() const
The base class of the type hierarchy.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
QualType getRecordType(const RecordDecl *Decl) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
Represents a call to a C++ constructor.
bool HasHiddenLTOVisibility(const CXXRecordDecl *RD)
Returns whether the given record has hidden LTO visibility and therefore may participate in (single-m...
const LangOptions & getLangOpts() const
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference...
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a C++ constructor within a class.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
const llvm::APInt & getSize() const
virtual llvm::BasicBlock * EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, const CXXRecordDecl *RD)
const CXXBaseSpecifier *const * path_const_iterator
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Expr * getInit() const
Get the initializer.
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
bool areArgsDestroyedLeftToRightInCallee() const
Are arguments to a call destroyed left to right in the callee? This is a fundamental language change...
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
llvm::Value * GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating)
GetVTTParameter - Return the VTT parameter that should be passed to a base constructor/destructor wit...
QualType getThisType(ASTContext &C) const
Returns the type of the this pointer.
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
CharUnits getNaturalTypeAlignment(QualType T, AlignmentSource *Source=nullptr, bool forPointeeType=false)
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
void emitImplicitAssignmentOperatorBody(FunctionArgList &Args)
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
The collection of all-type qualifiers we support.
static const CXXRecordDecl * LeastDerivedClassWithSameLayout(const CXXRecordDecl *RD)
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
emitDestroy - Immediately perform the destruction of the given object.
bool isVolatileQualified() const
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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...
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
const CXXRecordDecl * NearestVBase
llvm::SmallPtrSet< const CXXRecordDecl *, 4 > VisitedVirtualBasesSetTy
void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, Address This, Address Src, const CXXConstructExpr *E)
bool isReferenceType() const
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
llvm::IntegerType * SizeTy
void pushEHDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushEHDestroy - Push the standard destructor for the given type as an EH-only cleanup.
uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base)
getSubVTTIndex - Return the index of the sub-VTT for the base class of the given record decl...
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...
virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)=0
Checks if ABI requires to initilize vptrs for given dynamic class.
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, CGCalleeInfo CalleeInfo=CGCalleeInfo(), llvm::Instruction **callOrInvoke=nullptr)
EmitCall - Generate a call of the given function, expecting the given result type, and using the given argument list which specifies both the LLVM arguments and the types they were derived from.
CleanupKind getCleanupKind(QualType::DestructionKind kind)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
const Decl * getDecl() const
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, Address This, const CXXConstructExpr *E)
void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD)
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...
Address CreateIRTemp(QualType T, const Twine &Name="tmp")
CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0
Emit the ABI-specific prolog for the function.
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...
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...
static bool hasScalarEvaluationKind(QualType T)
Address GetAddrOfBlockDecl(const VarDecl *var, bool ByRef)
CharUnits getAlignment() const
virtual llvm::Value * EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr, const MemberPointerType *MPT)
Calculate an l-value from an object and a data member pointer.
const LangOptions & getLangOpts() const
IndirectFieldDecl * getIndirectMember() const
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
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...
QualType getReturnType() const
virtual llvm::Value * GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl)=0
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
bool isDefaulted() const
Whether this function is defaulted per C++0x.
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned char PointerWidthInBits
The width of a pointer into the generic address space.
field_range fields() const
llvm::PointerType * VoidPtrTy
A builtin binary operation expression such as "x + y" or "x <= y".
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind...
RecordDecl * getDecl() const
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
const SanitizerBlacklist & getSanitizerBlacklist() const
virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const =0
Determine whether it's possible to emit a vtable for RD, even though we do not know that the vtable h...
bool isVariadic() const
Whether this function is variadic.
Scope - A scope is a transient data structure that is used while parsing the program.
void incrementProfileCounter(const Stmt *S)
Increment the profiler's counter for the given statement.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
void EmitStmt(const Stmt *S)
EmitStmt - Emit the code for the statement.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy)
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
base_class_iterator bases_begin()
virtual void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This)=0
Emit the destructor call.
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
static const Expr * skipNoOpCastsAndParens(const Expr *E)
Checking the operand of a cast to a virtual base object.
detail::InMemoryDirectory::const_iterator I
static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init)
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
std::pair< CharUnits, CharUnits > getTypeInfoInChars(const Type *T) const
init_iterator init_begin()
Retrieve an iterator to the first initializer.
Represents the this expression in C++.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource AlignSource=AlignmentSource::Type)
static CharUnits One()
One - Construct a CharUnits quantity of one.
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask >> Checked, StringRef CheckName, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will call a handler function in a sanitizer runtime with the provided argum...
CompoundStmt - This represents a group of statements like { stmt stmt }.
Represents a prototype with parameter type info, e.g.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
const CodeGen::CGBlockInfo * BlockInfo
const TargetInfo & getTarget() const
param_type_iterator param_type_begin() const
static void EmitAggMemberInitializer(CodeGenFunction &CGF, LValue LHS, Expr *Init, Address ArrayIndexVar, QualType T, ArrayRef< VarDecl * > ArrayIndexes, unsigned Index)
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK)
bool hasConstructorVariants() const
Does this ABI have different entrypoints for complete-object and base-subobject constructors?
void setAddress(Address address)
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
Address getBitFieldAddress() const
static void EmitLValueForAnyFieldInitialization(CodeGenFunction &CGF, CXXCtorInitializer *MemberInit, LValue &LHS)
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
void DecorateInstructionWithTBAA(llvm::Instruction *Inst, llvm::MDNode *TBAAInfo, bool ConvertTypeToTag=true)
Decorate the instruction with a TBAA tag.
static TypeEvaluationKind getEvaluationKind(QualType T)
hasAggregateLLVMType - Return true if the specified AST type will map into an aggregate LLVM type or ...
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
CXXDtorType
C++ destructor types.
llvm::Value * getPointer() const
const Type * getTypeForDecl() const
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
CXXDtorType getDtorType() const
bool CanDevirtualizeMemberFunctionCall(const Expr *Base, const CXXMethodDecl *MD)
CanDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given expr can be devirtualized...
CGCXXABI & getCXXABI() const
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
static ParamValue forIndirect(Address addr)
void EmitVTableAssumptionLoad(const VPtr &vptr, Address This)
Emit assumption that vptr load == global vtable.
bool usesInAlloca() const
Return true if this function uses inalloca arguments.
void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, const ArrayType *ArrayTy, Address ArrayPtr, const CXXConstructExpr *E, bool ZeroInitialization=false)
EmitCXXAggrConstructorCall - Emit a loop to call a particular constructor for each of several members...
ArrayRef< NamedDecl * > chain() const
Represents a C++ destructor within a class.
capture_const_iterator capture_begin() const
const ParmVarDecl * getParamDecl(unsigned i) const
void EmitLambdaBlockInvokeBody()
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
ASTContext & getContext() const
void add(RValue rvalue, QualType type, bool needscopy=false)
void EmitAsanPrologueOrEpilogue(bool Prologue)
char __ovld __cnfn min(char x, char y)
Returns y if y < x, otherwise it returns x.
llvm::LLVMContext & getLLVMContext()
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
llvm::IntegerType * Int32Ty
ArrayRef< VarDecl * > getArrayIndices()
Expr * getSubExpr() const
bool isIndirectMemberInitializer() const
void EmitConstructorBody(FunctionArgList &Args)
EmitConstructorBody - Emits the body of the current constructor.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator, CallArgList &CallArgs)
void EmitAggregateCopyCtor(Address DestPtr, Address SrcPtr, QualType DestTy, QualType SrcTy)
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
ArrayRef< ParmVarDecl * > parameters() const
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
void EmitLambdaToBlockPointerBody(FunctionArgList &Args)
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=None)
unsigned getNumBases() const
Retrieves the number of base classes of this class.
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
forAddr - Make a slot for an aggregate value.
The COMDAT used for dtors.
GlobalDecl - represents a global declaration.
bool hasObjCLifetime() const
static const RecordType * getRecordType(QualType QT)
Checks that the passed in QualType either is of RecordType or points to RecordType.
The l-value was considered opaque, so the alignment was determined from a type.
static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor)
CanSkipVTablePointerInitialization - Check whether we need to initialize any vtable pointers before c...
Stmt * getBody(const FunctionDecl *&Definition) const
getBody - Retrieve the body (definition) of the function.
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
Enumerates target-specific builtins in their own namespaces within namespace clang.
virtual unsigned addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, CallArgList &Args)=0
Add any ABI-specific implicit arguments needed to call a constructor.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeSet ExtraAttrs=llvm::AttributeSet())
Create a new runtime function with the specified type and name.
Represents a call to an inherited base class constructor from an inheriting constructor.
bool mayInsertExtraPadding(bool EmitRemark=false) const
Whether we are allowed to insert extra padding between fields.
virtual bool NeedsVTTParameter(GlobalDecl GD)
Return whether the given global decl needs a VTT parameter.
void PushDestructorCleanup(QualType T, Address Addr)
PushDestructorCleanup - Push a cleanup to call the complete-object destructor of an object of the giv...
ASTContext & getContext() const
Encodes a location in the source.
CharUnits getPointerAlign() const
unsigned getNumParams() const
getNumParams - Return the number of parameters this function must have based on its FunctionType...
bool isBlacklistedType(StringRef MangledTypeName, StringRef Category=StringRef()) const
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
FieldDecl * getAnyMember() const
void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This)
Emit assumption load for all bases.
bool inheritingCtorHasParams(const InheritedConstructor &Inherited, CXXCtorType Type)
Determine if a C++ inheriting constructor should have parameters matching those of its inherited cons...
Represents a call to a member function that may be written either with member call syntax (e...
llvm::Metadata * CreateMetadataIdentifierForType(QualType T)
Create a metadata identifier for the given type.
Checking the operand of a cast to a base object.
init_iterator init_end()
Retrieve an iterator past the last initializer.
A scoped helper to set the current debug location to the specified location or preferred location of ...
llvm::GlobalVariable * GetAddrOfVTT(const CXXRecordDecl *RD)
GetAddrOfVTT - Get the address of the VTT for the given record decl.
Represents a static or instance method of a struct/union/class.
virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &Args) const =0
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
const CXXRecordDecl * getBestDynamicClassType() const
For an expression of class type or pointer to class type, return the most derived class decl the expr...
ArrayRef< ParmVarDecl * > parameters() const
bool isBaseVirtual() const
Returns whether the base is virtual or not.
SanitizerSet SanOpts
Sanitizers enabled for this function.
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
const CodeGenOptions & getCodeGenOpts() const
const LangOptions & getLangOpts() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
const T * castAs() const
Member-template castAs<specific type>.
unsigned getBuiltinID() const
Returns a value indicating whether this function corresponds to a builtin function.
llvm::Constant * getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, bool IsForDefinition=false)
Return the address of the constructor/destructor of the given type.
void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo)
EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
static ParamValue forDirect(llvm::Value *value)
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...
static void EmitBaseInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *BaseInit, CXXCtorType CtorType)
bool isDynamicClass() const
virtual bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr)=0
Checks if ABI requires extra virtual offset for vtable field.
CXXCtorType
C++ constructor types.
SourceLocation getLocation() const LLVM_READONLY
void InitializeVTablePointer(const VPtr &vptr)
Initialize the vtable pointer of the given subobject.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
bool isAnonymousStructOrUnion() const
isAnonymousStructOrUnion - Whether this is an anonymous struct or union.
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
CGFunctionInfo - Class to encapsulate the information about a function definition.
CharUnits getAlignment() const
Return the alignment of this pointer.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This)
void EmitVTablePtrCheckForCast(QualType T, llvm::Value *Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
bool isZero() const
isZero - Test whether the quantity equals zero.
Address CreateMemTemp(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignment...
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
static bool canEmitDelegateCallArgs(CodeGenFunction &CGF, const CXXConstructorDecl *Ctor, CXXCtorType Type, CallArgList &Args)
A scope within which we are constructing the fields of an object which might use a CXXDefaultInitExpr...
IndirectFieldDecl - An instance of this class is created to represent a field injected from an anonym...
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, const FunctionArgList &Args)
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor)
Checks whether the given constructor is a valid subject for the complete-to-base constructor delegati...
void InitializeVTablePointers(const CXXRecordDecl *ClassDecl)
detail::InMemoryDirectory::const_iterator E
A pointer to member type per C++ 8.3.3 - Pointers to members.
void EmitAggregateCopy(Address DestPtr, Address SrcPtr, QualType EltTy, bool isVolatile=false, bool isAssignment=false)
EmitAggregateCopy - Emit an aggregate copy.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
unsigned getNumArgs() const
CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the assumed alignment of a virtual base of a class.
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V, QualType Type, CharUnits Alignment=CharUnits::Zero(), bool SkipNullCheck=false)
Emit a check that V is the address of storage of the appropriate size and alignment for an object of ...
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type. ...
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
JumpDest ReturnBlock
ReturnBlock - Unified return block.
virtual void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF, const CXXRecordDecl *RD)
Emit the code to initialize hidden members required to handle virtual inheritance, if needed by the ABI.
virtual llvm::Constant * getVTableAddressPoint(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject.
llvm::PointerType * getType() const
Return the type of the pointer value.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
StructorType getFromCtorType(CXXCtorType T)
const T * getAs() const
Member-template getAs<specific type>'.
CharUnits OffsetFromNearestVBase
Represents a C++ base or member initializer.
Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base, llvm::Value *memberPtr, const MemberPointerType *memberPtrType, AlignmentSource *AlignSource=nullptr)
Emit the address of a field using a member data pointer.
llvm::PointerType * Int8PtrTy
void EmitLambdaStaticInvokeFunction(const CXXMethodDecl *MD)
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
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.
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
Expr * getArg(unsigned Arg)
Return the specified argument.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
ABIArgInfo & getReturnInfo()
Represents a base class of a C++ class.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases...
unsigned getFieldIndex() const
getFieldIndex - Returns the index of this field within its record, as appropriate for passing to ASTR...
bool isAnyMemberInitializer() const
void EmitFunctionBody(FunctionArgList &Args, const Stmt *Body)
std::string getQualifiedNameAsString() const
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
Address LoadCXXThisAddress()
A template argument list.
virtual llvm::Value * getVTableAddressPointInStructor(CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base, const CXXRecordDecl *NearestVBase)=0
Get the address point of the vtable for the given base subobject while building a constructor or a de...
const Type * getClass() const
llvm::IntegerType * PtrDiffTy
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
static void EmitMemberInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *MemberInit, const CXXConstructorDecl *Constructor, FunctionArgList &Args)
Represents a C++ struct/union/class.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block, taking care to avoid creation of branches from dummy blocks.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset...
llvm::Type * ConvertType(QualType T)
static Destroyer destroyCXXObject
LValue EmitLValue(const Expr *E)
EmitLValue - Emit code to compute a designator that specifies the location of the expression...
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
void EmitTrapCheck(llvm::Value *Checked)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it...
const BlockDecl * getBlockDecl() const
llvm::ConstantInt * CreateCrossDsoCfiTypeId(llvm::Metadata *MD)
Generate a cross-DSO type identifier for MD.
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
static bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit)
const FunctionDecl * getOperatorDelete() const
static Address ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, CharUnits nonVirtualOffset, llvm::Value *virtualOffset, const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase)
Struct with all informations about dynamic [sub]class needed to set vptr.
A reference to a declared variable, function, enum, etc.
static RValue get(llvm::Value *V)
void EmitDestructorBody(FunctionArgList &Args)
EmitDestructorBody - Emits the body of the current destructor.
void EmitCfiSlowPathCheck(SanitizerMask Kind, 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 ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
QualType getElementType() const
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
const CXXRecordDecl * VTableClass
CodeGenVTables & getVTables()
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
CodeGenTypes & getTypes() const
LValue - This represents an lvalue references.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Information for lazily generating a cleanup.
static bool HasTrivialDestructorBody(ASTContext &Context, const CXXRecordDecl *BaseClassDecl, const CXXRecordDecl *MostDerivedClassDecl)
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
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 hasTrivialBody() const
hasTrivialBody - Returns whether the function has a trivial body that does not require any specific c...
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, bool IsForDefinition=false)
Return the address of the given function.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
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 ...
CallArgList - Type for representing both the value and type of arguments in a call.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
base_class_range vbases()
Represents the canonical version of C arrays with a specified constant size.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
Declaration of a template function.
static bool FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field)
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
Structure with information about how a bitfield should be accessed.
llvm::MDNode * getTBAAInfoForVTablePtr()
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraArgs)
Arrange a call to a C++ method, passing the given arguments.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.