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 std::string VariableName;
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();
745 CI->getValue()->toString(Idx);
746 ArrayIndices = (llvm::Twine(
"[") + Idx.str() +
"]" + ArrayIndices).str();
754 const MemRegion *OR = SI->getAsSymbol()->getOriginRegion();
762 ArrayIndices = (llvm::Twine(
"[") + Idx +
"]" + ArrayIndices).str();
770 if (R->canPrintPrettyAsExpr()) {
771 R->printPrettyAsExpr(os);
772 return QuoteIfNeeded(llvm::Twine(os.str()) + ArrayIndices);
777 std::string Super = FR->getSuperRegion()->getDescriptiveName(
false);
780 return QuoteIfNeeded(Super +
"." + FR->getDecl()->getName());
789 if (
auto *FR = dyn_cast<FieldRegion>(
this)) {
790 return FR->getDecl()->getSourceRange();
794 return VR->getDecl()->getSourceRange();
810 switch (SR->getKind()) {
811 case MemRegion::AllocaRegionKind:
812 case MemRegion::SymbolicRegionKind:
814 case MemRegion::StringRegionKind:
818 case MemRegion::CompoundLiteralRegionKind:
819 case MemRegion::CXXBaseObjectRegionKind:
820 case MemRegion::CXXDerivedObjectRegionKind:
821 case MemRegion::CXXTempObjectRegionKind:
822 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
823 case MemRegion::CXXThisRegionKind:
824 case MemRegion::ObjCIvarRegionKind:
825 case MemRegion::NonParamVarRegionKind:
826 case MemRegion::ParamVarRegionKind:
827 case MemRegion::ElementRegionKind:
828 case MemRegion::ObjCStringRegionKind: {
838 case MemRegion::FieldRegionKind: {
851 const auto isFlexibleArrayMemberCandidate =
856 auto IsIncompleteArray = [](
const ArrayType *AT) {
859 auto IsArrayOfZero = [](
const ArrayType *AT) {
860 const auto *CAT = dyn_cast<ConstantArrayType>(AT);
861 return CAT && CAT->isZeroSize();
863 auto IsArrayOfOne = [](
const ArrayType *AT) {
864 const auto *CAT = dyn_cast<ConstantArrayType>(AT);
865 return CAT && CAT->getSize() == 1;
869 const FAMKind StrictFlexArraysLevel =
870 Ctx.getLangOpts().getStrictFlexArraysLevel();
875 if (StrictFlexArraysLevel == FAMKind::Default)
876 return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
878 if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
879 return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
881 if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete)
882 return IsArrayOfZero(AT) || IsIncompleteArray(AT);
884 assert(StrictFlexArraysLevel == FAMKind::IncompleteOnly);
885 return IsIncompleteArray(AT);
888 if (isFlexibleArrayMemberCandidate(Ctx.getAsArrayType(Ty)))
895 case MemRegion::BlockDataRegionKind:
896 case MemRegion::BlockCodeRegionKind:
897 case MemRegion::FunctionCodeRegionKind:
900 llvm_unreachable(
"Unhandled region");
904template <
typename REG>
905const REG *MemRegionManager::LazyAllocate(REG*& region) {
907 region =
new (A) REG(*
this);
913template <
typename REG,
typename ARG>
914const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
916 region =
new (A) REG(
this, a);
950 if (K == MemRegion::GlobalSystemSpaceRegionKind)
951 return LazyAllocate(SystemGlobals);
952 if (K == MemRegion::GlobalImmutableSpaceRegionKind)
953 return LazyAllocate(ImmutableGlobals);
954 assert(K == MemRegion::GlobalInternalSpaceRegionKind);
955 return LazyAllocate(InternalGlobals);
958 assert(K == MemRegion::StaticGlobalSpaceRegionKind);
968 return LazyAllocate(heap);
972 return LazyAllocate(unknown);
976 return LazyAllocate(code);
984 return getSubRegion<StringRegion>(
990 return getSubRegion<ObjCStringRegion>(
997static llvm::PointerUnion<const StackFrame *, const VarRegion *>
1005 if (Frame.getData()) {
1010 if (
const auto *VR = dyn_cast<VarRegion>(OrigR)) {
1011 if (VR->getDecl() == VD)
1033 (N ==
"stdin" || N ==
"stdout" || N ==
"stderr");
1038 const auto *PVD = dyn_cast<ParmVarDecl>(D);
1040 unsigned Index = PVD->getFunctionScopeIndex();
1044 bool CurrentParam =
true;
1045 if (
const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) {
1047 (Index < FD->param_size() && FD->getParamDecl(Index) == PVD);
1048 }
else if (
const auto *BD = dyn_cast<BlockDecl>(CalleeDecl)) {
1056 return getSubRegion<ParamVarRegion>(CallSite, Index,
1090 if (Ctx.getSourceManager().isInSystemHeader(D->
getLocation()) &&
1103 llvm::PointerUnion<const StackFrame *, const VarRegion *>
V =
1106 if (
const auto *VR = dyn_cast_if_present<const VarRegion *>(
V))
1127 else if (
const auto *BD = dyn_cast<BlockDecl>(STCD)) {
1165 return getSubRegion<NonParamVarRegion>(D, superR);
1172 return getSubRegion<ParamVarRegion>(OriginExpr, Index,
1185 bool IsArcManagedBlock = Ctx.getLangOpts().ObjCAutoRefCount;
1190 if (!IsArcManagedBlock && SF) {
1202 return getSubRegion<BlockDataRegion>(BC, SF, blockCount, sReg);
1210 if (
CL->isFileScope())
1217 return getSubRegion<CompoundLiteralRegion>(
CL, sReg);
1233 T = Ctx.getQualifiedType(T, Quals);
1236 llvm::FoldingSetNodeID ID;
1237 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
1240 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
1241 auto *R = cast_or_null<ElementRegion>(data);
1245 Regions.InsertNode(R, InsertPos);
1254 return getSubRegion<FunctionCodeRegion>(FD,
getCodeRegion());
1260 return getSubRegion<BlockCodeRegion>(BD, locTy, AC,
getCodeRegion());
1266 if (MemSpace ==
nullptr)
1268 return getSubRegion<SymbolicRegion>(sym, MemSpace);
1284 return getSubRegion<ObjCIvarRegion>(d, superRegion);
1298 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1305 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1315 BaseClass = BaseClass->getCanonicalDecl();
1324 for (
const auto &I : Class->bases()) {
1325 if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
1343 while (
const auto *
Base = dyn_cast<CXXBaseObjectRegion>(Super))
1349 return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
1355 return getSubRegion<CXXDerivedObjectRegion>(RD, Super);
1364 const auto *D = dyn_cast<CXXMethodDecl>(SF->
getDecl());
1368 while (!SF->
inTopFrame() && (!D || D->isStatic() ||
1371 D = dyn_cast<CXXMethodDecl>(SF->
getDecl());
1386 const auto *SR = dyn_cast<SubRegion>(
this);
1389 R = SR->getSuperRegion();
1390 SR = dyn_cast<SubRegion>(R);
1403 const MemSpaceRegion *
const *AssociatedSpace = State->get<MemSpacesMap>(MR);
1404 return AssociatedSpace ? *AssociatedSpace : RawSpace;
1416 return State->set<MemSpacesMap>(
Base, Space);
1424 switch (R->getKind()) {
1425 case MemRegion::ElementRegionKind:
1426 case MemRegion::FieldRegionKind:
1427 case MemRegion::ObjCIvarRegionKind:
1428 case MemRegion::CXXBaseObjectRegionKind:
1429 case MemRegion::CXXDerivedObjectRegionKind:
1443 while (
const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
1444 R = BR->getSuperRegion();
1459 switch (R->getKind()) {
1460 case ElementRegionKind: {
1462 if (!ER->getIndex().isZeroConstant())
1464 R = ER->getSuperRegion();
1467 case CXXBaseObjectRegionKind:
1468 case CXXDerivedObjectRegionKind:
1469 if (!StripBaseAndDerivedCasts)
1480 const auto *SubR = dyn_cast<SubRegion>(
this);
1483 if (
const auto *SymR = dyn_cast<SymbolicRegion>(SubR))
1485 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
1492 const ElementRegion *ER =
this;
1505 if (int64_t i = CI->getValue()->getSExtValue(); i != 0) {
1514 int64_t size =
C.getTypeSizeInChars(elemType).getQuantity();
1515 if (
auto NewOffset = llvm::checkedMulAdd(i, size, offset)) {
1516 offset = *NewOffset;
1518 LLVM_DEBUG(llvm::dbgs() <<
"MemRegion::getAsArrayOffset: "
1519 <<
"offset overflowing, returning unknown\n");
1526 ER = dyn_cast<ElementRegion>(superR);
1533 assert(superR &&
"super region cannot be NULL");
1540 assert(Child &&
"Child must not be null");
1544 for (
const auto &I : Child->bases()) {
1545 if (I.getType()->getAsCXXRecordDecl() ==
Base)
1553 const MemRegion *SymbolicOffsetBase =
nullptr;
1557 switch (R->getKind()) {
1558 case MemRegion::CodeSpaceRegionKind:
1559 case MemRegion::StackLocalsSpaceRegionKind:
1560 case MemRegion::StackArgumentsSpaceRegionKind:
1561 case MemRegion::HeapSpaceRegionKind:
1562 case MemRegion::UnknownSpaceRegionKind:
1563 case MemRegion::StaticGlobalSpaceRegionKind:
1564 case MemRegion::GlobalInternalSpaceRegionKind:
1565 case MemRegion::GlobalSystemSpaceRegionKind:
1566 case MemRegion::GlobalImmutableSpaceRegionKind:
1568 assert(Offset == 0 && !SymbolicOffsetBase);
1571 case MemRegion::FunctionCodeRegionKind:
1572 case MemRegion::BlockCodeRegionKind:
1573 case MemRegion::BlockDataRegionKind:
1577 SymbolicOffsetBase = R;
1580 case MemRegion::SymbolicRegionKind:
1581 case MemRegion::AllocaRegionKind:
1582 case MemRegion::CompoundLiteralRegionKind:
1583 case MemRegion::CXXThisRegionKind:
1584 case MemRegion::StringRegionKind:
1585 case MemRegion::ObjCStringRegionKind:
1586 case MemRegion::NonParamVarRegionKind:
1587 case MemRegion::ParamVarRegionKind:
1588 case MemRegion::CXXTempObjectRegionKind:
1589 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
1593 case MemRegion::ObjCIvarRegionKind:
1601 case MemRegion::CXXBaseObjectRegionKind: {
1603 R = BOR->getSuperRegion();
1606 bool RootIsSymbolic =
false;
1607 if (
const auto *TVR = dyn_cast<TypedValueRegion>(R)) {
1608 Ty = TVR->getDesugaredValueType(R->getContext());
1609 }
else if (
const auto *SR = dyn_cast<SymbolicRegion>(R)) {
1613 Ty = SR->getPointeeStaticType();
1614 RootIsSymbolic =
true;
1620 SymbolicOffsetBase = R;
1622 if (RootIsSymbolic) {
1626 if (BOR->isVirtual()) {
1627 if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
1628 SymbolicOffsetBase = R;
1631 SymbolicOffsetBase = R;
1638 if (SymbolicOffsetBase)
1642 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(Child);
1643 if (BOR->isVirtual())
1649 Offset += BaseOffset.
getQuantity() * R->getContext().getCharWidth();
1653 case MemRegion::CXXDerivedObjectRegionKind: {
1658 case MemRegion::ElementRegionKind: {
1660 R = ER->getSuperRegion();
1662 QualType EleTy = ER->getValueType();
1665 SymbolicOffsetBase = R;
1669 SVal Index = ER->getIndex();
1670 if (std::optional<nonloc::ConcreteInt> CI =
1674 if (SymbolicOffsetBase)
1677 int64_t i = CI->getValue()->getSExtValue();
1679 Offset += i * R->getContext().getTypeSize(EleTy);
1682 SymbolicOffsetBase = R;
1686 case MemRegion::FieldRegionKind: {
1688 R = FR->getSuperRegion();
1698 SymbolicOffsetBase = R;
1703 if (SymbolicOffsetBase)
1706 assert(FR->getDecl()->getCanonicalDecl() == FR->getDecl());
1707 auto MaybeFieldIdx = [FR, RD]() -> std::optional<unsigned> {
1708 for (
auto [Idx, Field] : llvm::enumerate(RD->
fields())) {
1709 if (FR->getDecl() == Field->getCanonicalDecl())
1712 return std::nullopt;
1715 if (!MaybeFieldIdx.has_value()) {
1716 assert(
false &&
"Field not found");
1720 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(RD);
1729 if (SymbolicOffsetBase)
1737 return *cachedOffset;
1744std::pair<const VarRegion *, const VarRegion *>
1745BlockDataRegion::getCaptureRegions(
const VarDecl *VD) {
1763 return std::make_pair(VR, OriginalVR);
1766void BlockDataRegion::LazyInitializeReferencedVars() {
1773 std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end());
1775 if (NumBlockVars == 0) {
1776 ReferencedVars = (
void*) 0x1;
1782 BumpVectorContext BC(A);
1784 using VarVec = BumpVector<const MemRegion *>;
1786 auto *BV =
new (A) VarVec(BC, NumBlockVars);
1787 auto *BVOriginal =
new (A) VarVec(BC, NumBlockVars);
1789 for (
const auto *VD : ReferencedBlockVars) {
1790 const VarRegion *VR =
nullptr;
1791 const VarRegion *OriginalVR =
nullptr;
1792 std::tie(VR, OriginalVR) = getCaptureRegions(VD);
1795 BV->push_back(VR, BC);
1796 BVOriginal->push_back(OriginalVR, BC);
1799 ReferencedVars = BV;
1800 OriginalVars = BVOriginal;
1805 const_cast<BlockDataRegion*
>(
this)->LazyInitializeReferencedVars();
1809 if (Vec == (
void*) 0x1)
1816 VecOriginal->begin());
1821 const_cast<BlockDataRegion*
>(
this)->LazyInitializeReferencedVars();
1825 if (Vec == (
void*) 0x1)
1832 VecOriginal->end());
1835llvm::iterator_range<BlockDataRegion::referenced_vars_iterator>
1842 if (I.getCapturedRegion() == R)
1843 return I.getOriginalRegion();
1854 SymTraitsMap[Sym] |= IK;
1860 if (
const auto *SR = dyn_cast<SymbolicRegion>(MR))
1863 MRTraitsMap[MR] |= IK;
1868 const_symbol_iterator I = SymTraitsMap.find(Sym);
1869 if (I != SymTraitsMap.end())
1870 return I->second & IK;
1880 if (
const auto *SR = dyn_cast<SymbolicRegion>(MR))
1881 return hasTrait(SR->getSymbol(), IK);
1883 const_region_iterator I = MRTraitsMap.find(MR);
1884 if (I != MRTraitsMap.end())
1885 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
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
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.
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.
std::string getDescriptiveName(bool UseQuotes=true) const
Get descriptive name for memory region.
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.
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)
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
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.