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,
391 ID.AddInteger(MemRegion::BlockDataRegionKind);
394 ID.AddInteger(BlkCount);
399 BlockDataRegion::ProfileRegion(ID, BC, LC, 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 std::string VariableName;
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();
746 CI->getValue()->toString(Idx);
747 ArrayIndices = (llvm::Twine(
"[") + Idx.str() +
"]" + ArrayIndices).str();
755 const MemRegion *OR = SI->getAsSymbol()->getOriginRegion();
763 ArrayIndices = (llvm::Twine(
"[") + Idx +
"]" + ArrayIndices).str();
771 if (R->canPrintPrettyAsExpr()) {
772 R->printPrettyAsExpr(os);
773 return QuoteIfNeeded(llvm::Twine(os.str()) + ArrayIndices);
778 std::string Super = FR->getSuperRegion()->getDescriptiveName(
false);
781 return QuoteIfNeeded(Super +
"." + FR->getDecl()->getName());
790 if (
auto *FR = dyn_cast<FieldRegion>(
this)) {
791 return FR->getDecl()->getSourceRange();
795 return VR->getDecl()->getSourceRange();
811 switch (SR->getKind()) {
812 case MemRegion::AllocaRegionKind:
813 case MemRegion::SymbolicRegionKind:
815 case MemRegion::StringRegionKind:
819 case MemRegion::CompoundLiteralRegionKind:
820 case MemRegion::CXXBaseObjectRegionKind:
821 case MemRegion::CXXDerivedObjectRegionKind:
822 case MemRegion::CXXTempObjectRegionKind:
823 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
824 case MemRegion::CXXThisRegionKind:
825 case MemRegion::ObjCIvarRegionKind:
826 case MemRegion::NonParamVarRegionKind:
827 case MemRegion::ParamVarRegionKind:
828 case MemRegion::ElementRegionKind:
829 case MemRegion::ObjCStringRegionKind: {
839 case MemRegion::FieldRegionKind: {
852 const auto isFlexibleArrayMemberCandidate =
857 auto IsIncompleteArray = [](
const ArrayType *AT) {
860 auto IsArrayOfZero = [](
const ArrayType *AT) {
861 const auto *CAT = dyn_cast<ConstantArrayType>(AT);
862 return CAT && CAT->isZeroSize();
864 auto IsArrayOfOne = [](
const ArrayType *AT) {
865 const auto *CAT = dyn_cast<ConstantArrayType>(AT);
866 return CAT && CAT->getSize() == 1;
870 const FAMKind StrictFlexArraysLevel =
871 Ctx.getLangOpts().getStrictFlexArraysLevel();
876 if (StrictFlexArraysLevel == FAMKind::Default)
877 return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
879 if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete)
880 return IsArrayOfOne(AT) || IsArrayOfZero(AT) || IsIncompleteArray(AT);
882 if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete)
883 return IsArrayOfZero(AT) || IsIncompleteArray(AT);
885 assert(StrictFlexArraysLevel == FAMKind::IncompleteOnly);
886 return IsIncompleteArray(AT);
889 if (isFlexibleArrayMemberCandidate(Ctx.getAsArrayType(Ty)))
896 case MemRegion::BlockDataRegionKind:
897 case MemRegion::BlockCodeRegionKind:
898 case MemRegion::FunctionCodeRegionKind:
901 llvm_unreachable(
"Unhandled region");
905template <
typename REG>
906const REG *MemRegionManager::LazyAllocate(REG*& region) {
908 region =
new (A) REG(*
this);
914template <
typename REG,
typename ARG>
915const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
917 region =
new (A) REG(
this, a);
951 if (K == MemRegion::GlobalSystemSpaceRegionKind)
952 return LazyAllocate(SystemGlobals);
953 if (K == MemRegion::GlobalImmutableSpaceRegionKind)
954 return LazyAllocate(ImmutableGlobals);
955 assert(K == MemRegion::GlobalInternalSpaceRegionKind);
956 return LazyAllocate(InternalGlobals);
959 assert(K == MemRegion::StaticGlobalSpaceRegionKind);
969 return LazyAllocate(heap);
973 return LazyAllocate(unknown);
977 return LazyAllocate(code);
985 return getSubRegion<StringRegion>(
991 return getSubRegion<ObjCStringRegion>(
998static llvm::PointerUnion<const StackFrame *, const VarRegion *>
1003 if (
const auto *SF = dyn_cast<StackFrame>(LC)) {
1006 if (SF->getData()) {
1011 if (
const auto *VR = dyn_cast<VarRegion>(OrigR)) {
1012 if (VR->getDecl() == VD)
1037 (N ==
"stdin" || N ==
"stdout" || N ==
"stderr");
1042 const auto *PVD = dyn_cast<ParmVarDecl>(D);
1044 unsigned Index = PVD->getFunctionScopeIndex();
1049 bool CurrentParam =
true;
1050 if (
const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) {
1052 (Index < FD->param_size() && FD->getParamDecl(Index) == PVD);
1053 }
else if (
const auto *BD = dyn_cast<BlockDecl>(CalleeDecl)) {
1061 return getSubRegion<ParamVarRegion>(CallSite, Index,
1095 if (Ctx.getSourceManager().isInSystemHeader(D->
getLocation()) &&
1108 llvm::PointerUnion<const StackFrame *, const VarRegion *>
V =
1111 if (
const auto *VR = dyn_cast_if_present<const VarRegion *>(
V))
1128 const Decl *STCD = SF->getDecl();
1132 else if (
const auto *BD = dyn_cast<BlockDecl>(STCD)) {
1149 BD, Ctx.getCanonicalType(T), SF->getAnalysisDeclContext());
1170 return getSubRegion<NonParamVarRegion>(D, superR);
1178 return getSubRegion<ParamVarRegion>(OriginExpr, Index,
1185 unsigned blockCount) {
1193 bool IsArcManagedBlock = Ctx.getLangOpts().ObjCAutoRefCount;
1198 if (!IsArcManagedBlock && LC) {
1211 return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg);
1219 if (
CL->isFileScope())
1227 return getSubRegion<CompoundLiteralRegion>(
CL, sReg);
1243 T = Ctx.getQualifiedType(T, Quals);
1246 llvm::FoldingSetNodeID ID;
1247 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
1250 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
1251 auto *R = cast_or_null<ElementRegion>(data);
1255 Regions.InsertNode(R, InsertPos);
1264 return getSubRegion<FunctionCodeRegion>(FD,
getCodeRegion());
1270 return getSubRegion<BlockCodeRegion>(BD, locTy, AC,
getCodeRegion());
1276 if (MemSpace ==
nullptr)
1278 return getSubRegion<SymbolicRegion>(sym, MemSpace);
1294 return getSubRegion<ObjCIvarRegion>(d, superRegion);
1310 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1317 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1327 BaseClass = BaseClass->getCanonicalDecl();
1336 for (
const auto &I : Class->bases()) {
1337 if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
1355 while (
const auto *
Base = dyn_cast<CXXBaseObjectRegion>(Super))
1361 return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
1367 return getSubRegion<CXXDerivedObjectRegion>(RD, Super);
1377 const auto *D = dyn_cast<CXXMethodDecl>(LC->
getDecl());
1381 while (!LC->
inTopFrame() && (!D || D->isStatic() ||
1384 D = dyn_cast<CXXMethodDecl>(LC->
getDecl());
1401 const auto *SR = dyn_cast<SubRegion>(
this);
1404 R = SR->getSuperRegion();
1405 SR = dyn_cast<SubRegion>(R);
1418 const MemSpaceRegion *
const *AssociatedSpace = State->get<MemSpacesMap>(MR);
1419 return AssociatedSpace ? *AssociatedSpace : RawSpace;
1431 return State->set<MemSpacesMap>(
Base, Space);
1439 switch (R->getKind()) {
1440 case MemRegion::ElementRegionKind:
1441 case MemRegion::FieldRegionKind:
1442 case MemRegion::ObjCIvarRegionKind:
1443 case MemRegion::CXXBaseObjectRegionKind:
1444 case MemRegion::CXXDerivedObjectRegionKind:
1458 while (
const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
1459 R = BR->getSuperRegion();
1474 switch (R->getKind()) {
1475 case ElementRegionKind: {
1477 if (!ER->getIndex().isZeroConstant())
1479 R = ER->getSuperRegion();
1482 case CXXBaseObjectRegionKind:
1483 case CXXDerivedObjectRegionKind:
1484 if (!StripBaseAndDerivedCasts)
1495 const auto *SubR = dyn_cast<SubRegion>(
this);
1498 if (
const auto *SymR = dyn_cast<SymbolicRegion>(SubR))
1500 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
1507 const ElementRegion *ER =
this;
1520 if (int64_t i = CI->getValue()->getSExtValue(); i != 0) {
1529 int64_t size =
C.getTypeSizeInChars(elemType).getQuantity();
1530 if (
auto NewOffset = llvm::checkedMulAdd(i, size, offset)) {
1531 offset = *NewOffset;
1533 LLVM_DEBUG(llvm::dbgs() <<
"MemRegion::getAsArrayOffset: "
1534 <<
"offset overflowing, returning unknown\n");
1541 ER = dyn_cast<ElementRegion>(superR);
1548 assert(superR &&
"super region cannot be NULL");
1555 assert(Child &&
"Child must not be null");
1559 for (
const auto &I : Child->bases()) {
1560 if (I.getType()->getAsCXXRecordDecl() ==
Base)
1568 const MemRegion *SymbolicOffsetBase =
nullptr;
1572 switch (R->getKind()) {
1573 case MemRegion::CodeSpaceRegionKind:
1574 case MemRegion::StackLocalsSpaceRegionKind:
1575 case MemRegion::StackArgumentsSpaceRegionKind:
1576 case MemRegion::HeapSpaceRegionKind:
1577 case MemRegion::UnknownSpaceRegionKind:
1578 case MemRegion::StaticGlobalSpaceRegionKind:
1579 case MemRegion::GlobalInternalSpaceRegionKind:
1580 case MemRegion::GlobalSystemSpaceRegionKind:
1581 case MemRegion::GlobalImmutableSpaceRegionKind:
1583 assert(Offset == 0 && !SymbolicOffsetBase);
1586 case MemRegion::FunctionCodeRegionKind:
1587 case MemRegion::BlockCodeRegionKind:
1588 case MemRegion::BlockDataRegionKind:
1592 SymbolicOffsetBase = R;
1595 case MemRegion::SymbolicRegionKind:
1596 case MemRegion::AllocaRegionKind:
1597 case MemRegion::CompoundLiteralRegionKind:
1598 case MemRegion::CXXThisRegionKind:
1599 case MemRegion::StringRegionKind:
1600 case MemRegion::ObjCStringRegionKind:
1601 case MemRegion::NonParamVarRegionKind:
1602 case MemRegion::ParamVarRegionKind:
1603 case MemRegion::CXXTempObjectRegionKind:
1604 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
1608 case MemRegion::ObjCIvarRegionKind:
1616 case MemRegion::CXXBaseObjectRegionKind: {
1618 R = BOR->getSuperRegion();
1621 bool RootIsSymbolic =
false;
1622 if (
const auto *TVR = dyn_cast<TypedValueRegion>(R)) {
1623 Ty = TVR->getDesugaredValueType(R->getContext());
1624 }
else if (
const auto *SR = dyn_cast<SymbolicRegion>(R)) {
1628 Ty = SR->getPointeeStaticType();
1629 RootIsSymbolic =
true;
1635 SymbolicOffsetBase = R;
1637 if (RootIsSymbolic) {
1641 if (BOR->isVirtual()) {
1642 if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
1643 SymbolicOffsetBase = R;
1646 SymbolicOffsetBase = R;
1653 if (SymbolicOffsetBase)
1657 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(Child);
1658 if (BOR->isVirtual())
1664 Offset += BaseOffset.
getQuantity() * R->getContext().getCharWidth();
1668 case MemRegion::CXXDerivedObjectRegionKind: {
1673 case MemRegion::ElementRegionKind: {
1675 R = ER->getSuperRegion();
1677 QualType EleTy = ER->getValueType();
1680 SymbolicOffsetBase = R;
1684 SVal Index = ER->getIndex();
1685 if (std::optional<nonloc::ConcreteInt> CI =
1689 if (SymbolicOffsetBase)
1692 int64_t i = CI->getValue()->getSExtValue();
1694 Offset += i * R->getContext().getTypeSize(EleTy);
1697 SymbolicOffsetBase = R;
1701 case MemRegion::FieldRegionKind: {
1703 R = FR->getSuperRegion();
1713 SymbolicOffsetBase = R;
1718 if (SymbolicOffsetBase)
1721 assert(FR->getDecl()->getCanonicalDecl() == FR->getDecl());
1722 auto MaybeFieldIdx = [FR, RD]() -> std::optional<unsigned> {
1723 for (
auto [Idx, Field] : llvm::enumerate(RD->
fields())) {
1724 if (FR->getDecl() == Field->getCanonicalDecl())
1727 return std::nullopt;
1730 if (!MaybeFieldIdx.has_value()) {
1731 assert(
false &&
"Field not found");
1735 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(RD);
1744 if (SymbolicOffsetBase)
1752 return *cachedOffset;
1759std::pair<const VarRegion *, const VarRegion *>
1760BlockDataRegion::getCaptureRegions(
const VarDecl *VD) {
1779 return std::make_pair(VR, OriginalVR);
1782void BlockDataRegion::LazyInitializeReferencedVars() {
1789 std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end());
1791 if (NumBlockVars == 0) {
1792 ReferencedVars = (
void*) 0x1;
1798 BumpVectorContext BC(A);
1800 using VarVec = BumpVector<const MemRegion *>;
1802 auto *BV =
new (A) VarVec(BC, NumBlockVars);
1803 auto *BVOriginal =
new (A) VarVec(BC, NumBlockVars);
1805 for (
const auto *VD : ReferencedBlockVars) {
1806 const VarRegion *VR =
nullptr;
1807 const VarRegion *OriginalVR =
nullptr;
1808 std::tie(VR, OriginalVR) = getCaptureRegions(VD);
1811 BV->push_back(VR, BC);
1812 BVOriginal->push_back(OriginalVR, BC);
1815 ReferencedVars = BV;
1816 OriginalVars = BVOriginal;
1821 const_cast<BlockDataRegion*
>(
this)->LazyInitializeReferencedVars();
1825 if (Vec == (
void*) 0x1)
1832 VecOriginal->begin());
1837 const_cast<BlockDataRegion*
>(
this)->LazyInitializeReferencedVars();
1841 if (Vec == (
void*) 0x1)
1848 VecOriginal->end());
1851llvm::iterator_range<BlockDataRegion::referenced_vars_iterator>
1858 if (I.getCapturedRegion() == R)
1859 return I.getOriginalRegion();
1870 SymTraitsMap[Sym] |= IK;
1876 if (
const auto *SR = dyn_cast<SymbolicRegion>(MR))
1879 MRTraitsMap[MR] |= IK;
1884 const_symbol_iterator I = SymTraitsMap.find(Sym);
1885 if (I != SymTraitsMap.end())
1886 return I->second & IK;
1896 if (
const auto *SR = dyn_cast<SymbolicRegion>(MR))
1897 return hasTrait(SR->getSymbol(), IK);
1899 const_region_iterator I = MRTraitsMap.find(MR);
1900 if (I != MRTraitsMap.end())
1901 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 llvm::PointerUnion< const StackFrame *, const VarRegion * > getStackOrCaptureRegionForDeclContext(const LocationContext *LC, const DeclContext *DC, const VarDecl *VD)
Look through a chain of LocationContexts to either find the StackFrame that matches a DeclContext,...
static bool isStdStreamVar(const VarDecl *D)
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.
__device__ __2f16 float __ockl_bool s
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
const Decl * getDecl() const
const LocationContext * getParent() const
It might return null.
const StackFrame * getStackFrame() const
virtual bool inTopFrame() const
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 (based on CallEvent).
const Expr * getCallSite() const
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".
const CXXThisRegion * getCXXThisRegion(QualType thisPointerTy, const LocationContext *LC)
getCXXThisRegion - Retrieve the [artificial] region associated with the parameter 'this'.
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 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 CompoundLiteralRegion * getCompoundLiteralRegion(const CompoundLiteralExpr *CL, const LocationContext *LC)
getCompoundLiteralRegion - Retrieve the region associated with a given CompoundLiteral.
const AllocaRegion * getAllocaRegion(const Expr *Ex, unsigned Cnt, const LocationContext *LC)
getAllocaRegion - Retrieve a region associated with a call to alloca().
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 VarRegion * getVarRegion(const VarDecl *VD, const LocationContext *LC)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
const NonParamVarRegion * getNonParamVarRegion(const VarDecl *VD, const MemRegion *superR)
getVarRegion - Retrieve or create the memory region associated with a specified VarDecl and LocationC...
const ObjCIvarRegion * getObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *superRegion)
getObjCIvarRegion - Retrieve or create the memory region associated with a specified Objective-c inst...
const SymbolicRegion * getSymbolicHeapRegion(SymbolRef sym)
Return a unique symbolic region belonging to heap memory space.
const ObjCStringRegion * getObjCStringRegion(const ObjCStringLiteral *Str)
const StringRegion * getStringRegion(const StringLiteral *Str)
ASTContext & getContext()
DefinedOrUnknownSVal getStaticSize(const MemRegion *MR, SValBuilder &SVB) const
const ParamVarRegion * getParamVarRegion(const Expr *OriginExpr, unsigned Index, const LocationContext *LC)
getParamVarRegion - Retrieve or create the memory region associated with a specified CallExpr,...
const CodeSpaceRegion * getCodeRegion()
const CXXLifetimeExtendedObjectRegion * getCXXLifetimeExtendedObjectRegion(Expr const *Ex, ValueDecl const *VD, LocationContext const *LC)
Create a CXXLifetimeExtendedObjectRegion for temporaries which are lifetime-extended by local referen...
const CXXTempObjectRegion * getCXXTempObjectRegion(Expr const *Ex, LocationContext const *LC)
const GlobalsSpaceRegion * getGlobalsRegion(MemRegion::Kind K=MemRegion::GlobalInternalSpaceRegionKind, const CodeTextRegion *R=nullptr)
getGlobalsRegion - Retrieve the memory region associated with global variables.
const SymbolicRegion * getSymbolicRegion(SymbolRef Sym, const MemSpaceRegion *MemSpace=nullptr)
Retrieve or create a "symbolic" memory region.
const FunctionCodeRegion * getFunctionCodeRegion(const NamedDecl *FD)
const BlockDataRegion * getBlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc, unsigned blockCount)
getBlockDataRegion - Get the memory region associated with an instance of a block.
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...
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.