35#include "llvm/ADT/APInt.h"
36#include "llvm/ADT/FoldingSet.h"
37#include "llvm/ADT/PointerUnion.h"
38#include "llvm/ADT/SmallString.h"
39#include "llvm/ADT/StringRef.h"
40#include "llvm/ADT/Twine.h"
41#include "llvm/ADT/iterator_range.h"
42#include "llvm/Support/Allocator.h"
43#include "llvm/Support/Casting.h"
44#include "llvm/Support/CheckedArithmetic.h"
45#include "llvm/Support/Compiler.h"
46#include "llvm/Support/Debug.h"
47#include "llvm/Support/ErrorHandling.h"
48#include "llvm/Support/raw_ostream.h"
60#define DEBUG_TYPE "MemRegion"
69[[maybe_unused]]
static bool isAReferenceTypedValueRegion(
const MemRegion *R) {
70 const auto *TyReg = llvm::dyn_cast<TypedValueRegion>(R);
71 return TyReg && TyReg->getValueType()->isReferenceType();
74template <
typename RegionTy,
typename SuperTy,
typename Arg1Ty>
75RegionTy* MemRegionManager::getSubRegion(
const Arg1Ty arg1,
76 const SuperTy *superRegion) {
77 llvm::FoldingSetNodeID
ID;
78 RegionTy::ProfileRegion(ID, arg1, superRegion);
80 auto *
R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, InsertPos));
83 R =
new (A) RegionTy(arg1, superRegion);
84 Regions.InsertNode(R, InsertPos);
85 assert(!isAReferenceTypedValueRegion(superRegion));
91template <
typename RegionTy,
typename SuperTy,
typename Arg1Ty,
typename Arg2Ty>
92RegionTy* MemRegionManager::getSubRegion(
const Arg1Ty arg1,
const Arg2Ty arg2,
93 const SuperTy *superRegion) {
94 llvm::FoldingSetNodeID
ID;
95 RegionTy::ProfileRegion(ID, arg1, arg2, superRegion);
97 auto *
R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, InsertPos));
100 R =
new (A) RegionTy(arg1, arg2, superRegion);
101 Regions.InsertNode(R, InsertPos);
102 assert(!isAReferenceTypedValueRegion(superRegion));
108template <
typename RegionTy,
typename SuperTy,
109 typename Arg1Ty,
typename Arg2Ty,
typename Arg3Ty>
110RegionTy* MemRegionManager::getSubRegion(
const Arg1Ty arg1,
const Arg2Ty arg2,
112 const SuperTy *superRegion) {
113 llvm::FoldingSetNodeID
ID;
114 RegionTy::ProfileRegion(ID, arg1, arg2, arg3, superRegion);
116 auto *
R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, InsertPos));
119 R =
new (A) RegionTy(arg1, arg2, arg3, superRegion);
120 Regions.InsertNode(R, InsertPos);
121 assert(!isAReferenceTypedValueRegion(superRegion));
146 if (
const auto *sr = dyn_cast<SubRegion>(r))
147 r = sr->getSuperRegion();
150 }
while (r !=
nullptr);
158 if (
const auto *sr = dyn_cast<SubRegion>(
superRegion)) {
168 return SSR ? SSR->getStackFrame() :
nullptr;
173 return SSR ? SSR->getStackFrame() :
nullptr;
178 "A temporary object can only be allocated on the stack");
183 :
DeclRegion(sReg, ObjCIvarRegionKind), IVD(ivd) {
203 "`ParamVarRegion` support functions without `Decl` not implemented"
211 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
212 assert(Index < FD->param_size());
213 return FD->parameters()[Index];
214 }
else if (
const auto *BD = dyn_cast<BlockDecl>(D)) {
215 assert(Index < BD->param_size());
216 return BD->parameters()[Index];
217 }
else if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
218 assert(Index < MD->param_size());
219 return MD->parameters()[Index];
220 }
else if (
const auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
221 assert(Index < CD->param_size());
222 return CD->parameters()[Index];
224 llvm_unreachable(
"Unexpected Decl kind!");
233 ID.AddInteger(
static_cast<unsigned>(
getKind()));
237 ID.AddInteger(
static_cast<unsigned>(
getKind()));
242 ID.AddInteger(
static_cast<unsigned>(
getKind()));
246void StringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
249 ID.AddInteger(
static_cast<unsigned>(StringRegionKind));
254void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
257 ID.AddInteger(
static_cast<unsigned>(ObjCStringRegionKind));
262void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
263 const Expr *Ex,
unsigned cnt,
265 ID.AddInteger(
static_cast<unsigned>(AllocaRegionKind));
279void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
282 ID.AddInteger(
static_cast<unsigned>(CompoundLiteralRegionKind));
287void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
290 ID.AddInteger(
static_cast<unsigned>(CXXThisRegionKind));
292 ID.AddPointer(sRegion);
296 CXXThisRegion::ProfileRegion(ID, ThisPointerTy,
superRegion);
303void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
306 ID.AddInteger(
static_cast<unsigned>(ObjCIvarRegionKind));
315void NonParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
318 ID.AddInteger(
static_cast<unsigned>(NonParamVarRegionKind));
327void ParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
const Expr *OE,
329 ID.AddInteger(
static_cast<unsigned>(ParamVarRegionKind));
341 ID.AddInteger(
static_cast<unsigned>(MemRegion::SymbolicRegionKind));
350void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
353 ID.AddInteger(MemRegion::ElementRegionKind);
360 ElementRegion::ProfileRegion(ID, ElementType, Index,
superRegion);
363void FunctionCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
366 ID.AddInteger(MemRegion::FunctionCodeRegionKind);
371 FunctionCodeRegion::ProfileRegion(ID, FD,
superRegion);
374void BlockCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
378 ID.AddInteger(MemRegion::BlockCodeRegionKind);
383 BlockCodeRegion::ProfileRegion(ID, BD, locTy, AC,
superRegion);
386void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
390 ID.AddInteger(MemRegion::BlockDataRegionKind);
393 ID.AddInteger(BlkCount);
398 BlockDataRegion::ProfileRegion(ID, BC, SF, BlockCount,
getSuperRegion());
401void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
412void CXXLifetimeExtendedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
422 llvm::FoldingSetNodeID &ID)
const {
426void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
431 ID.AddBoolean(IsVirtual);
439void CXXDerivedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
454void GlobalsSpaceRegion::anchor() {}
456void NonStaticGlobalSpaceRegion::anchor() {}
458void StackSpaceRegion::anchor() {}
460void TypedRegion::anchor() {}
462void TypedValueRegion::anchor() {}
464void CodeTextRegion::anchor() {}
466void SubRegion::anchor() {}
478 llvm::raw_string_ostream os(s);
484 os <<
"<Unknown Region>";
488 os <<
"alloca{S" << Ex->getID(
getContext()) <<
',' << Cnt <<
'}';
496 os <<
"block_code{" <<
static_cast<const void *
>(
this) <<
'}';
500 os <<
"block_data{" << BC;
503 os <<
"(" << Var.getCapturedRegion() <<
"<-" << Var.getOriginalRegion()
519 os <<
"lifetime_extended_object{" <<
getValueType() <<
", ";
523 os <<
"D" << ExD->getID();
554 assert(Str !=
nullptr &&
"Expecting non-null StringLiteral");
559 assert(Str !=
nullptr &&
"Expecting non-null ObjCStringLiteral");
566 os <<
"SymRegion{" << sym <<
'}';
573 os <<
"NonParamVarRegion{D" << VD->getID() <<
'}';
585 os <<
"CodeSpaceRegion";
589 os <<
"StaticGlobalsMemSpace{" << CR <<
'}';
593 os <<
"GlobalInternalSpaceRegion";
597 os <<
"GlobalSystemSpaceRegion";
601 os <<
"GlobalImmutableSpaceRegion";
605 os <<
"HeapSpaceRegion";
609 os <<
"UnknownSpaceRegion";
613 os <<
"StackArgumentsSpaceRegion";
617 os <<
"StackLocalsSpaceRegion";
623 "`ParamVarRegion` support functions without `Decl` not implemented"
628 os <<
"ParamVarRegion{P" << PVD->
getID() <<
'}';
642#define REGION(Id, Parent) \
645#include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
648 llvm_unreachable(
"Unkown kind!");
652 assert(
canPrintPretty() &&
"This region cannot be printed pretty.");
659 llvm_unreachable(
"This region cannot be printed pretty.");
672 "`ParamVarRegion` support functions without `Decl` not implemented"
726 bool AllowFallback)
const {
727 std::string ArrayIndices;
730 llvm::raw_svector_ostream os(buf);
733 auto QuoteIfNeeded = [UseQuotes](
const Twine &Subject) -> std::string {
735 return (
"'" + Subject +
"'").str();
736 return Subject.str();
739 auto FallbackName = [
this, AllowFallback]() -> std::string {
744 if (StringRef Name = FR->getDecl()->getName(); !Name.empty())
745 return (llvm::Twine(
"the field '") + Name +
"'").str();
746 return "the unnamed field";
750 return "the memory returned by 'alloca'";
753 return "the heap area";
756 return "the string literal";
767 CI->getValue()->toString(Idx);
768 ArrayIndices = (llvm::Twine(
"[") + Idx.str() +
"]" + ArrayIndices).str();
774 return FallbackName();
776 const MemRegion *OR = SI->getAsSymbol()->getOriginRegion();
778 return FallbackName();
782 return FallbackName();
784 ArrayIndices = (llvm::Twine(
"[") + Idx +
"]" + ArrayIndices).str();
792 if (R->canPrintPrettyAsExpr()) {
793 R->printPrettyAsExpr(os);
794 return QuoteIfNeeded(llvm::Twine(os.str()) + ArrayIndices);
799 std::string Super = FR->getSuperRegion()->getDescriptiveName(
false);
801 return FallbackName();
802 return QuoteIfNeeded(Super +
"." + FR->getDecl()->getName());
806 return FallbackName();
811 if (
auto *FR = dyn_cast<FieldRegion>(
this)) {
812 return FR->getDecl()->getSourceRange();
816 return VR->getDecl()->getSourceRange();
832 switch (SR->getKind()) {
833 case MemRegion::AllocaRegionKind:
834 case MemRegion::SymbolicRegionKind:
836 case MemRegion::StringRegionKind:
840 case MemRegion::CompoundLiteralRegionKind:
841 case MemRegion::CXXBaseObjectRegionKind:
842 case MemRegion::CXXDerivedObjectRegionKind:
843 case MemRegion::CXXTempObjectRegionKind:
844 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
845 case MemRegion::CXXThisRegionKind:
846 case MemRegion::ObjCIvarRegionKind:
847 case MemRegion::NonParamVarRegionKind:
848 case MemRegion::ParamVarRegionKind:
849 case MemRegion::ElementRegionKind:
850 case MemRegion::ObjCStringRegionKind: {
860 case MemRegion::FieldRegionKind: {
873 const auto isFlexibleArrayMemberCandidate =
878 auto IsIncompleteArray = [](
const ArrayType *AT) {
881 auto IsArrayOfZero = [](
const ArrayType *AT) {
882 const auto *CAT = dyn_cast<ConstantArrayType>(AT);
883 return CAT && CAT->isZeroSize();
885 auto IsArrayOfOne = [](
const ArrayType *AT) {
886 const auto *CAT = dyn_cast<ConstantArrayType>(AT);
887 return CAT && CAT->getSize() == 1;
891 const FAMKind StrictFlexArraysLevel =
892 Ctx.getLangOpts().getStrictFlexArraysLevel();
897 if (StrictFlexArraysLevel == FAMKind::Default)
898 return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
900 if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
901 return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
903 if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete)
904 return IsArrayOfZero(AT) || IsIncompleteArray(AT);
906 assert(StrictFlexArraysLevel == FAMKind::IncompleteOnly);
907 return IsIncompleteArray(AT);
910 if (isFlexibleArrayMemberCandidate(Ctx.getAsArrayType(Ty)))
917 case MemRegion::BlockDataRegionKind:
918 case MemRegion::BlockCodeRegionKind:
919 case MemRegion::FunctionCodeRegionKind:
922 llvm_unreachable(
"Unhandled region");
926template <
typename REG>
927const REG *MemRegionManager::LazyAllocate(REG*& region) {
929 region =
new (A) REG(*
this);
935template <
typename REG,
typename ARG>
936const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
938 region =
new (A) REG(
this, a);
972 if (K == MemRegion::GlobalSystemSpaceRegionKind)
973 return LazyAllocate(SystemGlobals);
974 if (K == MemRegion::GlobalImmutableSpaceRegionKind)
975 return LazyAllocate(ImmutableGlobals);
976 assert(K == MemRegion::GlobalInternalSpaceRegionKind);
977 return LazyAllocate(InternalGlobals);
980 assert(K == MemRegion::StaticGlobalSpaceRegionKind);
990 return LazyAllocate(heap);
994 return LazyAllocate(unknown);
998 return LazyAllocate(code);
1006 return getSubRegion<StringRegion>(
1012 return getSubRegion<ObjCStringRegion>(
1019static llvm::PointerUnion<const StackFrame *, const VarRegion *>
1027 if (Frame.getData()) {
1032 if (
const auto *VR = dyn_cast<VarRegion>(OrigR)) {
1033 if (VR->getDecl() == VD)
1055 (N ==
"stdin" || N ==
"stdout" || N ==
"stderr");
1061 const auto *PVD = dyn_cast<ParmVarDecl>(D);
1063 unsigned Index = PVD->getFunctionScopeIndex();
1067 bool CurrentParam =
true;
1068 if (
const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) {
1070 (Index < FD->param_size() && FD->getParamDecl(Index) == PVD);
1071 }
else if (
const auto *BD = dyn_cast<BlockDecl>(CalleeDecl)) {
1079 return getSubRegion<ParamVarRegion>(CallSite, Index,
1113 if (Ctx.getSourceManager().isInSystemHeader(D->
getLocation()) &&
1126 llvm::PointerUnion<const StackFrame *, const VarRegion *>
V =
1129 if (
const auto *VR = dyn_cast_if_present<const VarRegion *>(
V))
1150 else if (
const auto *BD = dyn_cast<BlockDecl>(STCD)) {
1188 return getSubRegion<NonParamVarRegion>(D, superR);
1195 return getSubRegion<ParamVarRegion>(OriginExpr, Index,
1208 bool IsArcManagedBlock = Ctx.getLangOpts().ObjCAutoRefCount;
1213 if (!IsArcManagedBlock && SF) {
1225 return getSubRegion<BlockDataRegion>(BC, SF, blockCount, sReg);
1233 if (
CL->isFileScope())
1240 return getSubRegion<CompoundLiteralRegion>(
CL, sReg);
1247 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
1256 T = Ctx.getQualifiedType(
T, Quals);
1259 llvm::FoldingSetNodeID ID;
1260 ElementRegion::ProfileRegion(ID,
T, Idx, superRegion);
1263 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
1264 auto *R = cast_or_null<ElementRegion>(data);
1268 Regions.InsertNode(R, InsertPos);
1277 return getSubRegion<FunctionCodeRegion>(FD,
getCodeRegion());
1283 return getSubRegion<BlockCodeRegion>(BD, locTy, AC,
getCodeRegion());
1289 if (MemSpace ==
nullptr)
1291 return getSubRegion<SymbolicRegion>(sym, MemSpace);
1307 return getSubRegion<ObjCIvarRegion>(d, superRegion);
1321 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1328 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1338 BaseClass = BaseClass->getCanonicalDecl();
1347 for (
const auto &I : Class->bases()) {
1348 if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
1366 while (
const auto *
Base = dyn_cast<CXXBaseObjectRegion>(Super))
1372 return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
1378 return getSubRegion<CXXDerivedObjectRegion>(RD, Super);
1387 const auto *D = dyn_cast<CXXMethodDecl>(SF->
getDecl());
1391 while (!SF->
inTopFrame() && (!D || D->isStatic() ||
1394 D = dyn_cast<CXXMethodDecl>(SF->
getDecl());
1409 const auto *SR = dyn_cast<SubRegion>(
this);
1412 R = SR->getSuperRegion();
1413 SR = dyn_cast<SubRegion>(R);
1426 const MemSpaceRegion *
const *AssociatedSpace = State->get<MemSpacesMap>(MR);
1427 return AssociatedSpace ? *AssociatedSpace : RawSpace;
1439 return State->set<MemSpacesMap>(
Base, Space);
1447 switch (R->getKind()) {
1448 case MemRegion::ElementRegionKind:
1449 case MemRegion::FieldRegionKind:
1450 case MemRegion::ObjCIvarRegionKind:
1451 case MemRegion::CXXBaseObjectRegionKind:
1452 case MemRegion::CXXDerivedObjectRegionKind:
1466 while (
const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
1467 R = BR->getSuperRegion();
1482 switch (R->getKind()) {
1483 case ElementRegionKind: {
1485 if (!ER->getIndex().isZeroConstant())
1487 R = ER->getSuperRegion();
1490 case CXXBaseObjectRegionKind:
1491 case CXXDerivedObjectRegionKind:
1492 if (!StripBaseAndDerivedCasts)
1503 const auto *SubR = dyn_cast<SubRegion>(
this);
1506 if (
const auto *SymR = dyn_cast<SymbolicRegion>(SubR))
1508 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
1515 const ElementRegion *ER =
this;
1528 if (int64_t i = CI->getValue()->getSExtValue(); i != 0) {
1537 int64_t size =
C.getTypeSizeInChars(elemType).getQuantity();
1538 if (
auto NewOffset = llvm::checkedMulAdd(i, size, offset)) {
1539 offset = *NewOffset;
1541 LLVM_DEBUG(llvm::dbgs() <<
"MemRegion::getAsArrayOffset: "
1542 <<
"offset overflowing, returning unknown\n");
1549 ER = dyn_cast<ElementRegion>(superR);
1556 assert(superR &&
"super region cannot be NULL");
1563 assert(Child &&
"Child must not be null");
1567 for (
const auto &I : Child->bases()) {
1568 if (I.getType()->getAsCXXRecordDecl() ==
Base)
1576 const MemRegion *SymbolicOffsetBase =
nullptr;
1580 switch (R->getKind()) {
1581 case MemRegion::CodeSpaceRegionKind:
1582 case MemRegion::StackLocalsSpaceRegionKind:
1583 case MemRegion::StackArgumentsSpaceRegionKind:
1584 case MemRegion::HeapSpaceRegionKind:
1585 case MemRegion::UnknownSpaceRegionKind:
1586 case MemRegion::StaticGlobalSpaceRegionKind:
1587 case MemRegion::GlobalInternalSpaceRegionKind:
1588 case MemRegion::GlobalSystemSpaceRegionKind:
1589 case MemRegion::GlobalImmutableSpaceRegionKind:
1591 assert(Offset == 0 && !SymbolicOffsetBase);
1594 case MemRegion::FunctionCodeRegionKind:
1595 case MemRegion::BlockCodeRegionKind:
1596 case MemRegion::BlockDataRegionKind:
1600 SymbolicOffsetBase = R;
1603 case MemRegion::SymbolicRegionKind:
1604 case MemRegion::AllocaRegionKind:
1605 case MemRegion::CompoundLiteralRegionKind:
1606 case MemRegion::CXXThisRegionKind:
1607 case MemRegion::StringRegionKind:
1608 case MemRegion::ObjCStringRegionKind:
1609 case MemRegion::NonParamVarRegionKind:
1610 case MemRegion::ParamVarRegionKind:
1611 case MemRegion::CXXTempObjectRegionKind:
1612 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
1616 case MemRegion::ObjCIvarRegionKind:
1624 case MemRegion::CXXBaseObjectRegionKind: {
1626 R = BOR->getSuperRegion();
1629 bool RootIsSymbolic =
false;
1630 if (
const auto *TVR = dyn_cast<TypedValueRegion>(R)) {
1631 Ty = TVR->getDesugaredValueType(R->getContext());
1632 }
else if (
const auto *SR = dyn_cast<SymbolicRegion>(R)) {
1636 Ty = SR->getPointeeStaticType();
1637 RootIsSymbolic =
true;
1643 SymbolicOffsetBase = R;
1645 if (RootIsSymbolic) {
1649 if (BOR->isVirtual()) {
1650 if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
1651 SymbolicOffsetBase = R;
1654 SymbolicOffsetBase = R;
1661 if (SymbolicOffsetBase)
1665 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(Child);
1666 if (BOR->isVirtual())
1672 Offset += BaseOffset.
getQuantity() * R->getContext().getCharWidth();
1676 case MemRegion::CXXDerivedObjectRegionKind: {
1681 case MemRegion::ElementRegionKind: {
1683 R = ER->getSuperRegion();
1685 QualType EleTy = ER->getValueType();
1688 SymbolicOffsetBase = R;
1692 SVal Index = ER->getIndex();
1693 if (std::optional<nonloc::ConcreteInt> CI =
1697 if (SymbolicOffsetBase)
1700 int64_t i = CI->getValue()->getSExtValue();
1702 Offset += i * R->getContext().getTypeSize(EleTy);
1705 SymbolicOffsetBase = R;
1709 case MemRegion::FieldRegionKind: {
1711 R = FR->getSuperRegion();
1721 SymbolicOffsetBase = R;
1726 if (SymbolicOffsetBase)
1729 assert(FR->getDecl()->getCanonicalDecl() == FR->getDecl());
1730 auto MaybeFieldIdx = [FR, RD]() -> std::optional<unsigned> {
1731 for (
auto [Idx, Field] : llvm::enumerate(RD->
fields())) {
1732 if (FR->getDecl() == Field->getCanonicalDecl())
1735 return std::nullopt;
1738 if (!MaybeFieldIdx.has_value()) {
1739 assert(
false &&
"Field not found");
1743 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(RD);
1752 if (SymbolicOffsetBase)
1760 return *cachedOffset;
1767std::pair<const VarRegion *, const VarRegion *>
1768BlockDataRegion::getCaptureRegions(
const VarDecl *VD) {
1786 return std::make_pair(VR, OriginalVR);
1789void BlockDataRegion::LazyInitializeReferencedVars() {
1796 std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end());
1798 if (NumBlockVars == 0) {
1799 ReferencedVars = (
void*) 0x1;
1805 BumpVectorContext BC(A);
1807 using VarVec = BumpVector<const MemRegion *>;
1809 auto *BV =
new (A) VarVec(BC, NumBlockVars);
1810 auto *BVOriginal =
new (A) VarVec(BC, NumBlockVars);
1812 for (
const auto *VD : ReferencedBlockVars) {
1813 const VarRegion *VR =
nullptr;
1814 const VarRegion *OriginalVR =
nullptr;
1815 std::tie(VR, OriginalVR) = getCaptureRegions(VD);
1818 BV->push_back(VR, BC);
1819 BVOriginal->push_back(OriginalVR, BC);
1822 ReferencedVars = BV;
1823 OriginalVars = BVOriginal;
1828 const_cast<BlockDataRegion*
>(
this)->LazyInitializeReferencedVars();
1832 if (Vec == (
void*) 0x1)
1839 VecOriginal->begin());
1844 const_cast<BlockDataRegion*
>(
this)->LazyInitializeReferencedVars();
1848 if (Vec == (
void*) 0x1)
1855 VecOriginal->end());
1858llvm::iterator_range<BlockDataRegion::referenced_vars_iterator>
1865 if (I.getCapturedRegion() == R)
1866 return I.getOriginalRegion();
1877 SymTraitsMap[Sym] |= IK;
1883 if (
const auto *SR = dyn_cast<SymbolicRegion>(MR))
1886 MRTraitsMap[MR] |= IK;
1891 const_symbol_iterator I = SymTraitsMap.find(Sym);
1892 if (I != SymTraitsMap.end())
1893 return I->second & IK;
1903 if (
const auto *SR = dyn_cast<SymbolicRegion>(MR))
1904 return hasTrait(SR->getSymbol(), IK);
1906 const_region_iterator I = MRTraitsMap.find(MR);
1907 if (I != MRTraitsMap.end())
1908 return I->second & IK;
Defines the clang::ASTContext interface.
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
static bool isStdStreamVar(const VarDecl *D)
static llvm::PointerUnion< const StackFrame *, const VarRegion * > getStackOrCaptureRegionForDeclContext(const StackFrame *SF, const DeclContext *DC, const VarDecl *VD)
Look through a chain of StackFrames to either find the StackFrame that matches a DeclContext,...
static bool isImmediateBase(const CXXRecordDecl *Child, const CXXRecordDecl *Base)
Returns true if Base is an immediate base class of Child.
static bool isValidBaseClass(const CXXRecordDecl *BaseClass, const TypedValueRegion *Super, bool IsVirtual)
Checks whether BaseClass is a valid virtual or direct non-virtual base class of the type of Super.
static RegionOffset calculateOffset(const MemRegion *R)
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
Defines the SourceManager interface.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getBlockPointerType(QualType T) const
Return the uniqued reference to the type for a block of the specified type.
QualType getFILEType() const
Retrieve the C FILE type.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
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.
AnalysisDeclContext contains the context data for the function, method or block under analysis.
llvm::iterator_range< referenced_decls_iterator > getReferencedBlockVars(const BlockDecl *BD)
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
size_t param_size() const
bool hasCaptures() const
True if this block (or its nested blocks) captures anything of local storage from its enclosing scope...
const ParmVarDecl * getParamDecl(unsigned i) const
TypeSourceInfo * getSignatureAsWritten() const
Represents a C++ struct/union/class.
bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is virtually derived from the class Base.
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CompoundLiteralExpr - [C99 6.5.2.5].
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
SourceLocation getLocation() const
DeclContext * getDeclContext()
std::string getAsString() const
Retrieve the human-readable string for this name.
This represents one expression.
Represents a member of a struct/union/class.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
FunctionType - C99 6.7.5.3 - Function Declarators.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
StrictFlexArraysLevelKind
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCStringLiteral, used for Objective-C string literals i.e.
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
LangAS getAddressSpace() const
Return the address space of this type.
QualType getCanonicalType() const
bool isConstQualified() const
Determine whether this type is const-qualified.
The collection of all-type qualifiers we support.
void setAddressSpace(LangAS space)
Represents a struct/union/class.
field_range fields() const
A trivial tuple used to represent a source range.
It represents a stack frame of the call stack.
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
const Expr * getCallSite() const
const Decl * getDecl() const
const StackFrame * getParent() const
It might return null.
llvm::iterator_range< parent_iterator > parentsIncludingSelf() const
Iterates over this frame followed by all of its ancestors.
StringLiteral - This represents a string literal expression, e.g.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
A container of type source information.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
const T * getAs() const
Member-template getAs<specific type>'.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
AllocaRegion - A region that represents an untyped blob of bytes created by a call to 'alloca'.
void dumpToStream(raw_ostream &os) const override
void Profile(llvm::FoldingSetNodeID &ID) const override
BlockCodeRegion - A region that represents code texts of blocks (closures).
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
void dumpToStream(raw_ostream &os) const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const BlockDecl * getDecl() const
void Profile(llvm::FoldingSetNodeID &ID) const override
BlockDataRegion - A region that represents a block instance.
const VarRegion * getOriginalRegion(const VarRegion *VR) const
Return the original region for a captured region, if one exists.
referenced_vars_iterator referenced_vars_begin() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const BlockCodeRegion * getCodeRegion() const
void Profile(llvm::FoldingSetNodeID &ID) const override
referenced_vars_iterator referenced_vars_end() const
void dumpToStream(raw_ostream &os) const override
friend class MemRegionManager
llvm::iterator_range< referenced_vars_iterator > referenced_vars() const
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
LLVM_ATTRIBUTE_RETURNS_NONNULL const CXXRecordDecl * getDecl() const
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
QualType getValueType() const override
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
void Profile(llvm::FoldingSetNodeID &ID) const override
QualType getValueType() const override
void dumpToStream(raw_ostream &os) const override
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
LLVM_ATTRIBUTE_RETURNS_NONNULL const CXXRecordDecl * getDecl() const
void Profile(llvm::FoldingSetNodeID &ID) const override
const StackFrame * getStackFrame() const
It might return null.
void dumpToStream(raw_ostream &os) const override
QualType getValueType() const override
QualType getValueType() const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const StackFrame * getStackFrame() const
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
CXXThisRegion - Represents the region for the implicit 'this' parameter in a call to a C++ method.
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
CodeSpaceRegion - The memory space that holds the executable code of functions and blocks.
void dumpToStream(raw_ostream &os) const override
CompoundLiteralRegion - A memory region representing a compound literal.
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
ElementRegion is used to represent both array elements and casts.
QualType getElementType() const
void Profile(llvm::FoldingSetNodeID &ID) const override
RegionRawOffset getAsArrayOffset() const
Compute the offset within the array. The array might also be a subobject.
void dumpToStream(raw_ostream &os) const override
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
bool canPrintPretty() const override
Returns true if this region can be printed in a user-friendly way.
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
void dumpToStream(raw_ostream &os) const override
void printPretty(raw_ostream &os) const override
Print the region for use in diagnostics.
void Profile(llvm::FoldingSetNodeID &ID) const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const FieldDecl * getDecl() const override
FunctionCodeRegion - A region that represents code texts of function.
const NamedDecl * getDecl() const
void dumpToStream(raw_ostream &os) const override
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
void dumpToStream(raw_ostream &os) const override
void dumpToStream(raw_ostream &os) const override
void dumpToStream(raw_ostream &os) const override
const HeapSpaceRegion * getHeapRegion()
getHeapRegion - Retrieve the memory region associated with the generic "heap".
llvm::BumpPtrAllocator & getAllocator()
const StackLocalsSpaceRegion * getStackLocalsRegion(const StackFrame *SF)
getStackLocalsRegion - Retrieve the memory region associated with the specified stack frame.
const FieldRegion * getFieldRegion(const FieldDecl *FD, const SubRegion *SuperRegion)
getFieldRegion - Retrieve or create the memory region associated with a specified FieldDecl.
const ParamVarRegion * getParamVarRegion(const Expr *OriginExpr, unsigned Index, const StackFrame *SF)
getParamVarRegion - Retrieve or create the memory region associated with a specified CallExpr,...
const StackArgumentsSpaceRegion * getStackArgumentsRegion(const StackFrame *SF)
getStackArgumentsRegion - Retrieve the memory region associated with function/method arguments of the...
const BlockCodeRegion * getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy, AnalysisDeclContext *AC)
const UnknownSpaceRegion * getUnknownRegion()
getUnknownRegion - Retrieve the memory region associated with unknown memory space.
const CXXDerivedObjectRegion * getCXXDerivedObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super)
Create a CXXDerivedObjectRegion with the given derived class for region Super.
const CXXLifetimeExtendedObjectRegion * getCXXLifetimeExtendedObjectRegion(Expr const *Ex, ValueDecl const *VD, StackFrame const *SF)
Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by local referen...
const CompoundLiteralRegion * getCompoundLiteralRegion(const CompoundLiteralExpr *CL, const StackFrame *SF)
getCompoundLiteralRegion - Retrieve the region associated with a given CompoundLiteral.
const ElementRegion * getElementRegion(QualType elementType, NonLoc Idx, const SubRegion *superRegion, const ASTContext &Ctx)
getElementRegion - Retrieve the memory region associated with the associated element type,...
const NonParamVarRegion * getNonParamVarRegion(const VarDecl *VD, const MemRegion *superR)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and StackFram...
const ObjCIvarRegion * getObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *superRegion)
getObjCIvarRegion - Retrieve or create the memory region associated with a specified Objective-c inst...
const VarRegion * getVarRegion(const VarDecl *VD, const StackFrame *SF)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and StackFram...
const AllocaRegion * getAllocaRegion(const Expr *Ex, unsigned Cnt, const StackFrame *SF)
getAllocaRegion - Retrieve a region associated with a call to alloca().
const SymbolicRegion * getSymbolicHeapRegion(SymbolRef sym)
Return a unique symbolic region belonging to heap memory space.
const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, StackFrame const *SF)
const ObjCStringRegion * getObjCStringRegion(const ObjCStringLiteral *Str)
const StringRegion * getStringRegion(const StringLiteral *Str)
ASTContext & getContext()
DefinedOrUnknownSVal getStaticSize(const MemRegion *MR, SValBuilder &SVB) const
const CodeSpaceRegion * getCodeRegion()
const GlobalsSpaceRegion * getGlobalsRegion(MemRegion::Kind K=MemRegion::GlobalInternalSpaceRegionKind, const CodeTextRegion *R=nullptr)
getGlobalsRegion - Retrieve the memory region associated with global variables.
const CXXThisRegion * getCXXThisRegion(QualType thisPointerTy, const StackFrame *SF)
getCXXThisRegion - Retrieve the [artificial] region associated with the parameter 'this'.
const SymbolicRegion * getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace=nullptr)
Retrieve or create a "symbolic" memory region.
const FunctionCodeRegion * getFunctionCodeRegion(const NamedDecl *FD)
const CXXBaseObjectRegion * getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super, bool IsVirtual)
Create a CXXBaseObjectRegion with the given base class for region Super.
const CXXLifetimeExtendedObjectRegion * getCXXStaticLifetimeExtendedObjectRegion(const Expr *Ex, ValueDecl const *VD)
Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by static refere...
const BlockDataRegion * getBlockDataRegion(const BlockCodeRegion *bc, const StackFrame *SF, unsigned blockCount)
getBlockDataRegion - Get the memory region associated with an instance of a block.
MemRegion - The root abstract class for all memory regions.
virtual bool canPrintPrettyAsExpr() const
Returns true if this region's textual representation can be used as part of a larger expression.
std::string getDescriptiveName(bool UseQuotes=true, bool AllowFallback=false) const
Get descriptive name for memory region.
StringRef getKindStr() const
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * StripCasts(bool StripBaseAndDerivedCasts=true) const
ProgramStateRef setMemorySpace(ProgramStateRef State, const MemSpaceRegion *Space) const
Set the dynamically deduced memory space of a MemRegion that currently has UnknownSpaceRegion.
ASTContext & getContext() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace(ProgramStateRef State) const
Returns the most specific memory space for this memory region in the given ProgramStateRef.
virtual bool isSubRegionOf(const MemRegion *R) const
Check if the region is a subregion of the given region.
virtual void dumpToStream(raw_ostream &os) const
const SymbolicRegion * getSymbolicBase() const
If this is a symbolic region, returns the region.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
virtual void printPretty(raw_ostream &os) const
Print the region for use in diagnostics.
virtual void printPrettyAsExpr(raw_ostream &os) const
Print the region as expression.
std::string getString() const
Get a string representation of a region for debug use.
const RegionTy * getAs() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getMostDerivedObjectRegion() const
Recursively retrieve the region of the most derived class instance of regions of C++ base class insta...
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getRawMemorySpace() const
Deprecated.
virtual bool canPrintPretty() const
Returns true if this region can be printed in a user-friendly way.
SourceRange sourceRange() const
Retrieve source range from memory region.
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
void Profile(llvm::FoldingSetNodeID &ID) const override
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
void Profile(llvm::FoldingSetNodeID &ID) const override
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
void dumpToStream(raw_ostream &os) const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const VarDecl * getDecl() const override
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
void Profile(llvm::FoldingSetNodeID &ID) const override
QualType getValueType() const override
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
LLVM_ATTRIBUTE_RETURNS_NONNULL const ObjCIvarDecl * getDecl() const override
void dumpToStream(raw_ostream &os) const override
The region associated with an ObjCStringLiteral.
void dumpToStream(raw_ostream &os) const override
ParamVarRegion - Represents a region for parameters.
bool canPrintPrettyAsExpr() const override
Returns true if this region's textual representation can be used as part of a larger expression.
LLVM_ATTRIBUTE_RETURNS_NONNULL const Expr * getOriginExpr() const
const ParmVarDecl * getDecl() const override
TODO: What does this return?
unsigned getIndex() const
void Profile(llvm::FoldingSetNodeID &ID) const override
QualType getValueType() const override
void dumpToStream(raw_ostream &os) const override
void printPrettyAsExpr(raw_ostream &os) const override
Print the region as expression.
InvalidationKinds
Describes different invalidation traits.
bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const
void setTrait(SymbolRef Sym, InvalidationKinds IK)
Represent a region's offset within the top level base region.
static const int64_t Symbolic
CharUnits getOffset() const
void dumpToStream(raw_ostream &os) const
const MemRegion * getRegion() const
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
QualType getArrayIndexType() const
SymbolManager & getSymbolManager()
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
void Profile(llvm::FoldingSetNodeID &ID) const
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
void dumpToStream(raw_ostream &os) const override
void dumpToStream(raw_ostream &os) const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const StackFrame * getStackFrame() const
void Profile(llvm::FoldingSetNodeID &ID) const override
The region of the static variables within the current CodeTextRegion scope.
void Profile(llvm::FoldingSetNodeID &ID) const override
void dumpToStream(raw_ostream &os) const override
LLVM_ATTRIBUTE_RETURNS_NONNULL const CodeTextRegion * getCodeRegion() const
StringRegion - Region associated with a StringLiteral.
void dumpToStream(raw_ostream &os) const override
SubRegion - A region that subsets another larger region.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const
bool isSubRegionOf(const MemRegion *R) const override
Check if the region is a subregion of the given region.
SubRegion(const MemRegion *sReg, Kind k)
const MemRegion * superRegion
MemRegionManager & getMemRegionManager() const override
SymbolExtent - Represents the extent (size in bytes) of a bounded region.
const SymExprT * acquire(Args &&...args)
Create or retrieve a SymExpr of type SymExprT for the given arguments.
SymbolicRegion - A special, "non-concrete" region.
void dumpToStream(raw_ostream &os) const override
void Profile(llvm::FoldingSetNodeID &ID) const override
static void ProfileRegion(llvm::FoldingSetNodeID &ID, SymbolRef sym, const MemRegion *superRegion)
TypedValueRegion - An abstract class representing regions having a typed value.
virtual QualType getValueType() const =0
void dumpToStream(raw_ostream &os) const override
const StackFrame * getStackFrame() const
It might return null.
Value representing integer constant.
Represents symbolic expression that isn't a location.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
const SymExpr * SymbolRef
DefinedOrUnknownSVal getElementExtent(QualType Ty, SValBuilder &SVB)
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
const FunctionProtoType * T
LangAS
Defines the address space values used by the address space qualifier of QualType.
U cast(CodeGen::Address addr)
Extra information about a function prototype.
Describes how types, statements, expressions, and declarations should be printed.