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);
79 llvm::FoldingSetInsertToken InsertToken;
80 auto *
R = cast_or_null<RegionTy>(Regions.lookup(ID, InsertToken));
83 R =
new (A) RegionTy(arg1, superRegion);
84 Regions.insert(R, InsertToken);
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);
96 llvm::FoldingSetInsertToken InsertToken;
97 auto *
R = cast_or_null<RegionTy>(Regions.lookup(ID, InsertToken));
100 R =
new (A) RegionTy(arg1, arg2, superRegion);
101 Regions.insert(R, InsertToken);
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);
115 llvm::FoldingSetInsertToken InsertToken;
116 auto *
R = cast_or_null<RegionTy>(Regions.lookup(ID, InsertToken));
119 R =
new (A) RegionTy(arg1, arg2, arg3, superRegion);
120 Regions.insert(R, InsertToken);
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"
210 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
211 assert(Index < FD->param_size());
212 return FD->parameters()[Index];
214 if (
const auto *BD = dyn_cast<BlockDecl>(D)) {
215 assert(Index < BD->param_size());
216 return BD->parameters()[Index];
218 if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
219 assert(Index < MD->param_size());
220 return MD->parameters()[Index];
222 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
223 assert(Index < CD->param_size());
224 return CD->parameters()[Index];
226 llvm_unreachable(
"Unexpected Decl kind!");
234 ID.AddInteger(
static_cast<unsigned>(
getKind()));
238 ID.AddInteger(
static_cast<unsigned>(
getKind()));
243 ID.AddInteger(
static_cast<unsigned>(
getKind()));
247void StringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
250 ID.AddInteger(
static_cast<unsigned>(StringRegionKind));
255void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
258 ID.AddInteger(
static_cast<unsigned>(ObjCStringRegionKind));
263void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
264 const Expr *Ex,
unsigned cnt,
266 ID.AddInteger(
static_cast<unsigned>(AllocaRegionKind));
280void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
283 ID.AddInteger(
static_cast<unsigned>(CompoundLiteralRegionKind));
288void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
291 ID.AddInteger(
static_cast<unsigned>(CXXThisRegionKind));
293 ID.AddPointer(sRegion);
297 CXXThisRegion::ProfileRegion(ID, ThisPointerTy,
superRegion);
304void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
307 ID.AddInteger(
static_cast<unsigned>(ObjCIvarRegionKind));
316void NonParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
319 ID.AddInteger(
static_cast<unsigned>(NonParamVarRegionKind));
328void ParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
const Expr *OE,
330 ID.AddInteger(
static_cast<unsigned>(ParamVarRegionKind));
342 ID.AddInteger(
static_cast<unsigned>(MemRegion::SymbolicRegionKind));
351void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
354 ID.AddInteger(MemRegion::ElementRegionKind);
361 ElementRegion::ProfileRegion(ID, ElementType, Index,
superRegion);
364void FunctionCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
367 ID.AddInteger(MemRegion::FunctionCodeRegionKind);
372 FunctionCodeRegion::ProfileRegion(ID, FD,
superRegion);
375void BlockCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
379 ID.AddInteger(MemRegion::BlockCodeRegionKind);
384 BlockCodeRegion::ProfileRegion(ID, BD, locTy, AC,
superRegion);
387void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
391 ID.AddInteger(MemRegion::BlockDataRegionKind);
394 ID.AddInteger(BlkCount);
399 BlockDataRegion::ProfileRegion(ID, BC, SF, BlockCount,
getSuperRegion());
402void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
413void CXXLifetimeExtendedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
423 llvm::FoldingSetNodeID &ID)
const {
427void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
432 ID.AddBoolean(IsVirtual);
440void CXXDerivedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
455void GlobalsSpaceRegion::anchor() {}
457void NonStaticGlobalSpaceRegion::anchor() {}
459void StackSpaceRegion::anchor() {}
461void TypedRegion::anchor() {}
463void TypedValueRegion::anchor() {}
465void CodeTextRegion::anchor() {}
467void SubRegion::anchor() {}
479 llvm::raw_string_ostream os(s);
485 os <<
"<Unknown Region>";
489 os <<
"alloca{S" << Ex->getID(
getContext()) <<
',' << Cnt <<
'}';
497 os <<
"block_code{" <<
static_cast<const void *
>(
this) <<
'}';
501 os <<
"block_data{" << BC;
504 os <<
"(" << Var.getCapturedRegion() <<
"<-" << Var.getOriginalRegion()
520 os <<
"lifetime_extended_object{" <<
getValueType() <<
", ";
524 os <<
"D" << ExD->getID();
555 assert(Str !=
nullptr &&
"Expecting non-null StringLiteral");
560 assert(Str !=
nullptr &&
"Expecting non-null ObjCStringLiteral");
567 os <<
"SymRegion{" << sym <<
'}';
574 os <<
"NonParamVarRegion{D" << VD->getID() <<
'}';
586 os <<
"CodeSpaceRegion";
590 os <<
"StaticGlobalsMemSpace{" << CR <<
'}';
594 os <<
"GlobalInternalSpaceRegion";
598 os <<
"GlobalSystemSpaceRegion";
602 os <<
"GlobalImmutableSpaceRegion";
606 os <<
"HeapSpaceRegion";
610 os <<
"UnknownSpaceRegion";
614 os <<
"StackArgumentsSpaceRegion";
618 os <<
"StackLocalsSpaceRegion";
624 "`ParamVarRegion` support functions without `Decl` not implemented"
629 os <<
"ParamVarRegion{P" << PVD->
getID() <<
'}';
643#define REGION(Id, Parent) \
646#include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
649 llvm_unreachable(
"Unkown kind!");
653 assert(
canPrintPretty() &&
"This region cannot be printed pretty.");
660 llvm_unreachable(
"This region cannot be printed pretty.");
673 "`ParamVarRegion` support functions without `Decl` not implemented"
727 bool AllowFallback)
const {
728 std::string ArrayIndices;
731 llvm::raw_svector_ostream os(buf);
734 auto QuoteIfNeeded = [UseQuotes](
const Twine &Subject) -> std::string {
736 return (
"'" + Subject +
"'").str();
737 return Subject.str();
740 auto FallbackName = [
this, AllowFallback]() -> std::string {
745 if (StringRef Name = FR->getDecl()->getName(); !Name.empty())
746 return (llvm::Twine(
"the field '") + Name +
"'").str();
747 return "the unnamed field";
751 return "the memory returned by 'alloca'";
754 return "the heap area";
757 return "the string literal";
768 CI->getValue()->toString(Idx);
769 ArrayIndices = (llvm::Twine(
"[") + Idx.str() +
"]" + ArrayIndices).str();
775 return FallbackName();
777 const MemRegion *OR = SI->getAsSymbol()->getOriginRegion();
779 return FallbackName();
783 return FallbackName();
785 ArrayIndices = (llvm::Twine(
"[") + Idx +
"]" + ArrayIndices).str();
793 if (R->canPrintPrettyAsExpr()) {
794 R->printPrettyAsExpr(os);
795 return QuoteIfNeeded(llvm::Twine(os.str()) + ArrayIndices);
800 std::string Super = FR->getSuperRegion()->getDescriptiveName(
false);
802 return FallbackName();
803 return QuoteIfNeeded(Super +
"." + FR->getDecl()->getName());
807 return FallbackName();
812 if (
auto *FR = dyn_cast<FieldRegion>(
this)) {
813 return FR->getDecl()->getSourceRange();
817 return VR->getDecl()->getSourceRange();
833 switch (SR->getKind()) {
834 case MemRegion::AllocaRegionKind:
835 case MemRegion::SymbolicRegionKind:
837 case MemRegion::StringRegionKind:
841 case MemRegion::CompoundLiteralRegionKind:
842 case MemRegion::CXXBaseObjectRegionKind:
843 case MemRegion::CXXDerivedObjectRegionKind:
844 case MemRegion::CXXTempObjectRegionKind:
845 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
846 case MemRegion::CXXThisRegionKind:
847 case MemRegion::ObjCIvarRegionKind:
848 case MemRegion::NonParamVarRegionKind:
849 case MemRegion::ParamVarRegionKind:
850 case MemRegion::ElementRegionKind:
851 case MemRegion::ObjCStringRegionKind: {
861 case MemRegion::FieldRegionKind: {
874 const auto isFlexibleArrayMemberCandidate =
879 auto IsIncompleteArray = [](
const ArrayType *AT) {
882 auto IsArrayOfZero = [](
const ArrayType *AT) {
883 const auto *CAT = dyn_cast<ConstantArrayType>(AT);
884 return CAT && CAT->isZeroSize();
886 auto IsArrayOfOne = [](
const ArrayType *AT) {
887 const auto *CAT = dyn_cast<ConstantArrayType>(AT);
888 return CAT && CAT->getSize() == 1;
892 const FAMKind StrictFlexArraysLevel =
893 Ctx.getLangOpts().getStrictFlexArraysLevel();
898 if (StrictFlexArraysLevel == FAMKind::Default)
899 return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
901 if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
902 return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
904 if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete)
905 return IsArrayOfZero(AT) || IsIncompleteArray(AT);
907 assert(StrictFlexArraysLevel == FAMKind::IncompleteOnly);
908 return IsIncompleteArray(AT);
911 if (isFlexibleArrayMemberCandidate(Ctx.getAsArrayType(Ty)))
918 case MemRegion::BlockDataRegionKind:
919 case MemRegion::BlockCodeRegionKind:
920 case MemRegion::FunctionCodeRegionKind:
923 llvm_unreachable(
"Unhandled region");
927template <
typename REG>
928const REG *MemRegionManager::LazyAllocate(REG*& region) {
930 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);
971 if (K == MemRegion::GlobalSystemSpaceRegionKind)
972 return LazyAllocate(SystemGlobals);
973 if (K == MemRegion::GlobalImmutableSpaceRegionKind)
974 return LazyAllocate(ImmutableGlobals);
975 assert(K == MemRegion::GlobalInternalSpaceRegionKind);
976 return LazyAllocate(InternalGlobals);
979 assert(K == MemRegion::StaticGlobalSpaceRegionKind);
989 return LazyAllocate(heap);
993 return LazyAllocate(unknown);
997 return LazyAllocate(code);
1005 return getSubRegion<StringRegion>(
1011 return getSubRegion<ObjCStringRegion>(
1018static llvm::PointerUnion<const StackFrame *, const VarRegion *>
1026 if (Frame.getData()) {
1031 if (
const auto *VR = dyn_cast<VarRegion>(OrigR)) {
1032 if (VR->getDecl() == VD)
1054 (N ==
"stdin" || N ==
"stdout" || N ==
"stderr");
1060 const auto *PVD = dyn_cast<ParmVarDecl>(D);
1062 unsigned Index = PVD->getFunctionScopeIndex();
1066 bool CurrentParam =
true;
1067 if (
const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) {
1069 (Index < FD->param_size() && FD->getParamDecl(Index) == PVD);
1070 }
else if (
const auto *BD = dyn_cast<BlockDecl>(CalleeDecl)) {
1078 return getSubRegion<ParamVarRegion>(CallSite, Index,
1114 if (Ctx.getSourceManager().isInSystemHeader(D->
getLocation()) &&
1127 llvm::PointerUnion<const StackFrame *, const VarRegion *>
V =
1130 if (
const auto *VR = dyn_cast_if_present<const VarRegion *>(
V))
1151 else if (
const auto *BD = dyn_cast<BlockDecl>(STCD)) {
1189 return getSubRegion<NonParamVarRegion>(D, superR);
1196 return getSubRegion<ParamVarRegion>(OriginExpr, Index,
1209 bool IsArcManagedBlock = Ctx.getLangOpts().ObjCAutoRefCount;
1214 if (!IsArcManagedBlock && SF) {
1226 return getSubRegion<BlockDataRegion>(BC, SF, blockCount, sReg);
1234 if (
CL->isFileScope()) {
1241 return getSubRegion<CompoundLiteralRegion>(
CL, sReg);
1248 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
1257 T = Ctx.getQualifiedType(
T, Quals);
1260 llvm::FoldingSetNodeID ID;
1261 ElementRegion::ProfileRegion(ID,
T, Idx, superRegion);
1263 llvm::FoldingSetInsertToken InsertToken;
1264 MemRegion *data = Regions.lookup(ID, InsertToken);
1265 auto *R = cast_or_null<ElementRegion>(data);
1269 Regions.insert(R, InsertToken);
1278 return getSubRegion<FunctionCodeRegion>(FD,
getCodeRegion());
1284 return getSubRegion<BlockCodeRegion>(BD, locTy, AC,
getCodeRegion());
1290 if (MemSpace ==
nullptr)
1292 return getSubRegion<SymbolicRegion>(sym, MemSpace);
1308 return getSubRegion<ObjCIvarRegion>(d, superRegion);
1322 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1329 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1339 BaseClass = BaseClass->getCanonicalDecl();
1348 for (
const auto &I : Class->bases()) {
1349 if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
1367 while (
const auto *
Base = dyn_cast<CXXBaseObjectRegion>(Super))
1373 return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
1379 return getSubRegion<CXXDerivedObjectRegion>(RD, Super);
1388 const auto *D = dyn_cast<CXXMethodDecl>(SF->
getDecl());
1392 while (!SF->
inTopFrame() && (!D || D->isStatic() ||
1395 D = dyn_cast<CXXMethodDecl>(SF->
getDecl());
1410 const auto *SR = dyn_cast<SubRegion>(
this);
1413 R = SR->getSuperRegion();
1414 SR = dyn_cast<SubRegion>(R);
1427 const MemSpaceRegion *
const *AssociatedSpace = State->get<MemSpacesMap>(MR);
1428 return AssociatedSpace ? *AssociatedSpace : RawSpace;
1440 return State->set<MemSpacesMap>(
Base, Space);
1448 switch (R->getKind()) {
1449 case MemRegion::ElementRegionKind:
1450 case MemRegion::FieldRegionKind:
1451 case MemRegion::ObjCIvarRegionKind:
1452 case MemRegion::CXXBaseObjectRegionKind:
1453 case MemRegion::CXXDerivedObjectRegionKind:
1467 while (
const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
1468 R = BR->getSuperRegion();
1483 switch (R->getKind()) {
1484 case ElementRegionKind: {
1486 if (!ER->getIndex().isZeroConstant())
1488 R = ER->getSuperRegion();
1491 case CXXBaseObjectRegionKind:
1492 case CXXDerivedObjectRegionKind:
1493 if (!StripBaseAndDerivedCasts)
1504 const auto *SubR = dyn_cast<SubRegion>(
this);
1507 if (
const auto *SymR = dyn_cast<SymbolicRegion>(SubR))
1509 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
1516 const ElementRegion *ER =
this;
1529 if (int64_t i = CI->getValue()->getSExtValue(); i != 0) {
1538 int64_t size =
C.getTypeSizeInChars(elemType).getQuantity();
1539 if (
auto NewOffset = llvm::checkedMulAdd(i, size, offset)) {
1540 offset = *NewOffset;
1542 LLVM_DEBUG(llvm::dbgs() <<
"MemRegion::getAsArrayOffset: "
1543 <<
"offset overflowing, returning unknown\n");
1550 ER = dyn_cast<ElementRegion>(superR);
1557 assert(superR &&
"super region cannot be NULL");
1564 assert(Child &&
"Child must not be null");
1568 for (
const auto &I : Child->bases()) {
1569 if (I.getType()->getAsCXXRecordDecl() ==
Base)
1577 const MemRegion *SymbolicOffsetBase =
nullptr;
1581 switch (R->getKind()) {
1582 case MemRegion::CodeSpaceRegionKind:
1583 case MemRegion::StackLocalsSpaceRegionKind:
1584 case MemRegion::StackArgumentsSpaceRegionKind:
1585 case MemRegion::HeapSpaceRegionKind:
1586 case MemRegion::UnknownSpaceRegionKind:
1587 case MemRegion::StaticGlobalSpaceRegionKind:
1588 case MemRegion::GlobalInternalSpaceRegionKind:
1589 case MemRegion::GlobalSystemSpaceRegionKind:
1590 case MemRegion::GlobalImmutableSpaceRegionKind:
1592 assert(Offset == 0 && !SymbolicOffsetBase);
1595 case MemRegion::FunctionCodeRegionKind:
1596 case MemRegion::BlockCodeRegionKind:
1597 case MemRegion::BlockDataRegionKind:
1601 SymbolicOffsetBase = R;
1604 case MemRegion::SymbolicRegionKind:
1605 case MemRegion::AllocaRegionKind:
1606 case MemRegion::CompoundLiteralRegionKind:
1607 case MemRegion::CXXThisRegionKind:
1608 case MemRegion::StringRegionKind:
1609 case MemRegion::ObjCStringRegionKind:
1610 case MemRegion::NonParamVarRegionKind:
1611 case MemRegion::ParamVarRegionKind:
1612 case MemRegion::CXXTempObjectRegionKind:
1613 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
1617 case MemRegion::ObjCIvarRegionKind:
1625 case MemRegion::CXXBaseObjectRegionKind: {
1627 R = BOR->getSuperRegion();
1630 bool RootIsSymbolic =
false;
1631 if (
const auto *TVR = dyn_cast<TypedValueRegion>(R)) {
1632 Ty = TVR->getDesugaredValueType(R->getContext());
1633 }
else if (
const auto *SR = dyn_cast<SymbolicRegion>(R)) {
1637 Ty = SR->getPointeeStaticType();
1638 RootIsSymbolic =
true;
1644 SymbolicOffsetBase = R;
1646 if (RootIsSymbolic) {
1650 if (BOR->isVirtual()) {
1651 if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
1652 SymbolicOffsetBase = R;
1655 SymbolicOffsetBase = R;
1662 if (SymbolicOffsetBase)
1666 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(Child);
1667 if (BOR->isVirtual())
1673 Offset += BaseOffset.
getQuantity() * R->getContext().getCharWidth();
1677 case MemRegion::CXXDerivedObjectRegionKind: {
1682 case MemRegion::ElementRegionKind: {
1684 R = ER->getSuperRegion();
1686 QualType EleTy = ER->getValueType();
1689 SymbolicOffsetBase = R;
1693 SVal Index = ER->getIndex();
1694 if (std::optional<nonloc::ConcreteInt> CI =
1698 if (SymbolicOffsetBase)
1701 int64_t i = CI->getValue()->getSExtValue();
1703 Offset += i * R->getContext().getTypeSize(EleTy);
1706 SymbolicOffsetBase = R;
1710 case MemRegion::FieldRegionKind: {
1712 R = FR->getSuperRegion();
1722 SymbolicOffsetBase = R;
1727 if (SymbolicOffsetBase)
1730 assert(FR->getDecl()->getCanonicalDecl() == FR->getDecl());
1731 auto MaybeFieldIdx = [FR, RD]() -> std::optional<unsigned> {
1732 for (
auto [Idx, Field] : llvm::enumerate(RD->
fields())) {
1733 if (FR->getDecl() == Field->getCanonicalDecl())
1736 return std::nullopt;
1739 if (!MaybeFieldIdx.has_value()) {
1740 assert(
false &&
"Field not found");
1744 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(RD);
1753 if (SymbolicOffsetBase)
1761 return *cachedOffset;
1768std::pair<const VarRegion *, const VarRegion *>
1769BlockDataRegion::getCaptureRegions(
const VarDecl *VD) {
1787 return std::make_pair(VR, OriginalVR);
1790void BlockDataRegion::LazyInitializeReferencedVars() {
1797 std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end());
1799 if (NumBlockVars == 0) {
1800 ReferencedVars = (
void*) 0x1;
1806 BumpVectorContext BC(A);
1808 using VarVec = BumpVector<const MemRegion *>;
1810 auto *BV =
new (A) VarVec(BC, NumBlockVars);
1811 auto *BVOriginal =
new (A) VarVec(BC, NumBlockVars);
1813 for (
const auto *VD : ReferencedBlockVars) {
1814 const VarRegion *VR =
nullptr;
1815 const VarRegion *OriginalVR =
nullptr;
1816 std::tie(VR, OriginalVR) = getCaptureRegions(VD);
1819 BV->push_back(VR, BC);
1820 BVOriginal->push_back(OriginalVR, BC);
1823 ReferencedVars = BV;
1824 OriginalVars = BVOriginal;
1829 const_cast<BlockDataRegion*
>(
this)->LazyInitializeReferencedVars();
1833 if (Vec == (
void*) 0x1)
1840 VecOriginal->begin());
1845 const_cast<BlockDataRegion*
>(
this)->LazyInitializeReferencedVars();
1849 if (Vec == (
void*) 0x1)
1856 VecOriginal->end());
1859llvm::iterator_range<BlockDataRegion::referenced_vars_iterator>
1866 if (I.getCapturedRegion() == R)
1867 return I.getOriginalRegion();
1878 SymTraitsMap[Sym] |= IK;
1884 if (
const auto *SR = dyn_cast<SymbolicRegion>(MR))
1887 MRTraitsMap[MR] |= IK;
1892 const_symbol_iterator I = SymTraitsMap.find(Sym);
1893 if (I != SymTraitsMap.end())
1894 return I->second & IK;
1904 if (
const auto *SR = dyn_cast<SymbolicRegion>(MR))
1905 return hasTrait(SR->getSymbol(), IK);
1907 const_region_iterator I = MRTraitsMap.find(MR);
1908 if (I != MRTraitsMap.end())
1909 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.
static bool hasLayout(const RecordDecl *D)
Whether layout (offset and size) information can be queried for D.
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.
This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits fromQuantity(QuantityType Quantity)
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.
A container of type source information.
bool isFunctionReferenceType() const
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.