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 *>
1009 if (
const auto *VR = dyn_cast<VarRegion>(OrigR)) {
1010 if (VR->getDecl() == VD)
1034 (N ==
"stdin" || N ==
"stdout" || N ==
"stderr");
1039 const auto *PVD = dyn_cast<ParmVarDecl>(D);
1041 unsigned Index = PVD->getFunctionScopeIndex();
1045 bool CurrentParam =
true;
1046 if (
const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl)) {
1048 (Index < FD->param_size() && FD->getParamDecl(Index) == PVD);
1049 }
else if (
const auto *BD = dyn_cast<BlockDecl>(CalleeDecl)) {
1057 return getSubRegion<ParamVarRegion>(CallSite, Index,
1091 if (Ctx.getSourceManager().isInSystemHeader(D->
getLocation()) &&
1104 llvm::PointerUnion<const StackFrame *, const VarRegion *>
V =
1107 if (
const auto *VR = dyn_cast_if_present<const VarRegion *>(
V))
1128 else if (
const auto *BD = dyn_cast<BlockDecl>(STCD)) {
1166 return getSubRegion<NonParamVarRegion>(D, superR);
1173 return getSubRegion<ParamVarRegion>(OriginExpr, Index,
1186 bool IsArcManagedBlock = Ctx.getLangOpts().ObjCAutoRefCount;
1191 if (!IsArcManagedBlock && SF) {
1203 return getSubRegion<BlockDataRegion>(BC, SF, blockCount, sReg);
1211 if (
CL->isFileScope())
1218 return getSubRegion<CompoundLiteralRegion>(
CL, sReg);
1234 T = Ctx.getQualifiedType(T, Quals);
1237 llvm::FoldingSetNodeID ID;
1238 ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
1241 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
1242 auto *R = cast_or_null<ElementRegion>(data);
1246 Regions.InsertNode(R, InsertPos);
1255 return getSubRegion<FunctionCodeRegion>(FD,
getCodeRegion());
1261 return getSubRegion<BlockCodeRegion>(BD, locTy, AC,
getCodeRegion());
1267 if (MemSpace ==
nullptr)
1269 return getSubRegion<SymbolicRegion>(sym, MemSpace);
1285 return getSubRegion<ObjCIvarRegion>(d, superRegion);
1299 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1306 return getSubRegion<CXXLifetimeExtendedObjectRegion>(
1316 BaseClass = BaseClass->getCanonicalDecl();
1325 for (
const auto &I : Class->bases()) {
1326 if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
1344 while (
const auto *
Base = dyn_cast<CXXBaseObjectRegion>(Super))
1350 return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super);
1356 return getSubRegion<CXXDerivedObjectRegion>(RD, Super);
1365 const auto *D = dyn_cast<CXXMethodDecl>(SF->
getDecl());
1369 while (!SF->
inTopFrame() && (!D || D->isStatic() ||
1372 D = dyn_cast<CXXMethodDecl>(SF->
getDecl());
1387 const auto *SR = dyn_cast<SubRegion>(
this);
1390 R = SR->getSuperRegion();
1391 SR = dyn_cast<SubRegion>(R);
1404 const MemSpaceRegion *
const *AssociatedSpace = State->get<MemSpacesMap>(MR);
1405 return AssociatedSpace ? *AssociatedSpace : RawSpace;
1417 return State->set<MemSpacesMap>(
Base, Space);
1425 switch (R->getKind()) {
1426 case MemRegion::ElementRegionKind:
1427 case MemRegion::FieldRegionKind:
1428 case MemRegion::ObjCIvarRegionKind:
1429 case MemRegion::CXXBaseObjectRegionKind:
1430 case MemRegion::CXXDerivedObjectRegionKind:
1444 while (
const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
1445 R = BR->getSuperRegion();
1460 switch (R->getKind()) {
1461 case ElementRegionKind: {
1463 if (!ER->getIndex().isZeroConstant())
1465 R = ER->getSuperRegion();
1468 case CXXBaseObjectRegionKind:
1469 case CXXDerivedObjectRegionKind:
1470 if (!StripBaseAndDerivedCasts)
1481 const auto *SubR = dyn_cast<SubRegion>(
this);
1484 if (
const auto *SymR = dyn_cast<SymbolicRegion>(SubR))
1486 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
1493 const ElementRegion *ER =
this;
1506 if (int64_t i = CI->getValue()->getSExtValue(); i != 0) {
1515 int64_t size =
C.getTypeSizeInChars(elemType).getQuantity();
1516 if (
auto NewOffset = llvm::checkedMulAdd(i, size, offset)) {
1517 offset = *NewOffset;
1519 LLVM_DEBUG(llvm::dbgs() <<
"MemRegion::getAsArrayOffset: "
1520 <<
"offset overflowing, returning unknown\n");
1527 ER = dyn_cast<ElementRegion>(superR);
1534 assert(superR &&
"super region cannot be NULL");
1541 assert(Child &&
"Child must not be null");
1545 for (
const auto &I : Child->bases()) {
1546 if (I.getType()->getAsCXXRecordDecl() ==
Base)
1554 const MemRegion *SymbolicOffsetBase =
nullptr;
1558 switch (R->getKind()) {
1559 case MemRegion::CodeSpaceRegionKind:
1560 case MemRegion::StackLocalsSpaceRegionKind:
1561 case MemRegion::StackArgumentsSpaceRegionKind:
1562 case MemRegion::HeapSpaceRegionKind:
1563 case MemRegion::UnknownSpaceRegionKind:
1564 case MemRegion::StaticGlobalSpaceRegionKind:
1565 case MemRegion::GlobalInternalSpaceRegionKind:
1566 case MemRegion::GlobalSystemSpaceRegionKind:
1567 case MemRegion::GlobalImmutableSpaceRegionKind:
1569 assert(Offset == 0 && !SymbolicOffsetBase);
1572 case MemRegion::FunctionCodeRegionKind:
1573 case MemRegion::BlockCodeRegionKind:
1574 case MemRegion::BlockDataRegionKind:
1578 SymbolicOffsetBase = R;
1581 case MemRegion::SymbolicRegionKind:
1582 case MemRegion::AllocaRegionKind:
1583 case MemRegion::CompoundLiteralRegionKind:
1584 case MemRegion::CXXThisRegionKind:
1585 case MemRegion::StringRegionKind:
1586 case MemRegion::ObjCStringRegionKind:
1587 case MemRegion::NonParamVarRegionKind:
1588 case MemRegion::ParamVarRegionKind:
1589 case MemRegion::CXXTempObjectRegionKind:
1590 case MemRegion::CXXLifetimeExtendedObjectRegionKind:
1594 case MemRegion::ObjCIvarRegionKind:
1602 case MemRegion::CXXBaseObjectRegionKind: {
1604 R = BOR->getSuperRegion();
1607 bool RootIsSymbolic =
false;
1608 if (
const auto *TVR = dyn_cast<TypedValueRegion>(R)) {
1609 Ty = TVR->getDesugaredValueType(R->getContext());
1610 }
else if (
const auto *SR = dyn_cast<SymbolicRegion>(R)) {
1614 Ty = SR->getPointeeStaticType();
1615 RootIsSymbolic =
true;
1621 SymbolicOffsetBase = R;
1623 if (RootIsSymbolic) {
1627 if (BOR->isVirtual()) {
1628 if (!Child->isVirtuallyDerivedFrom(BOR->getDecl()))
1629 SymbolicOffsetBase = R;
1632 SymbolicOffsetBase = R;
1639 if (SymbolicOffsetBase)
1643 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(Child);
1644 if (BOR->isVirtual())
1650 Offset += BaseOffset.
getQuantity() * R->getContext().getCharWidth();
1654 case MemRegion::CXXDerivedObjectRegionKind: {
1659 case MemRegion::ElementRegionKind: {
1661 R = ER->getSuperRegion();
1663 QualType EleTy = ER->getValueType();
1666 SymbolicOffsetBase = R;
1670 SVal Index = ER->getIndex();
1671 if (std::optional<nonloc::ConcreteInt> CI =
1675 if (SymbolicOffsetBase)
1678 int64_t i = CI->getValue()->getSExtValue();
1680 Offset += i * R->getContext().getTypeSize(EleTy);
1683 SymbolicOffsetBase = R;
1687 case MemRegion::FieldRegionKind: {
1689 R = FR->getSuperRegion();
1699 SymbolicOffsetBase = R;
1704 if (SymbolicOffsetBase)
1707 assert(FR->getDecl()->getCanonicalDecl() == FR->getDecl());
1708 auto MaybeFieldIdx = [FR, RD]() -> std::optional<unsigned> {
1709 for (
auto [Idx, Field] : llvm::enumerate(RD->
fields())) {
1710 if (FR->getDecl() == Field->getCanonicalDecl())
1713 return std::nullopt;
1716 if (!MaybeFieldIdx.has_value()) {
1717 assert(
false &&
"Field not found");
1721 const ASTRecordLayout &Layout = R->getContext().getASTRecordLayout(RD);
1730 if (SymbolicOffsetBase)
1738 return *cachedOffset;
1745std::pair<const VarRegion *, const VarRegion *>
1746BlockDataRegion::getCaptureRegions(
const VarDecl *VD) {
1764 return std::make_pair(VR, OriginalVR);
1767void BlockDataRegion::LazyInitializeReferencedVars() {
1774 std::distance(ReferencedBlockVars.begin(), ReferencedBlockVars.end());
1776 if (NumBlockVars == 0) {
1777 ReferencedVars = (
void*) 0x1;
1783 BumpVectorContext BC(A);
1785 using VarVec = BumpVector<const MemRegion *>;
1787 auto *BV =
new (A) VarVec(BC, NumBlockVars);
1788 auto *BVOriginal =
new (A) VarVec(BC, NumBlockVars);
1790 for (
const auto *VD : ReferencedBlockVars) {
1791 const VarRegion *VR =
nullptr;
1792 const VarRegion *OriginalVR =
nullptr;
1793 std::tie(VR, OriginalVR) = getCaptureRegions(VD);
1796 BV->push_back(VR, BC);
1797 BVOriginal->push_back(OriginalVR, BC);
1800 ReferencedVars = BV;
1801 OriginalVars = BVOriginal;
1806 const_cast<BlockDataRegion*
>(
this)->LazyInitializeReferencedVars();
1810 if (Vec == (
void*) 0x1)
1817 VecOriginal->begin());
1822 const_cast<BlockDataRegion*
>(
this)->LazyInitializeReferencedVars();
1826 if (Vec == (
void*) 0x1)
1833 VecOriginal->end());
1836llvm::iterator_range<BlockDataRegion::referenced_vars_iterator>
1843 if (I.getCapturedRegion() == R)
1844 return I.getOriginalRegion();
1855 SymTraitsMap[Sym] |= IK;
1861 if (
const auto *SR = dyn_cast<SymbolicRegion>(MR))
1864 MRTraitsMap[MR] |= IK;
1869 const_symbol_iterator I = SymTraitsMap.find(Sym);
1870 if (I != SymTraitsMap.end())
1871 return I->second & IK;
1881 if (
const auto *SR = dyn_cast<SymbolicRegion>(MR))
1882 return hasTrait(SR->getSymbol(), IK);
1884 const_region_iterator I = MRTraitsMap.find(MR);
1885 if (I != MRTraitsMap.end())
1886 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.
const void * getData() const
LLVM_ATTRIBUTE_RETURNS_NONNULL AnalysisDeclContext * getAnalysisDeclContext() const
const Expr * getCallSite() const
const Decl * getDecl() const
const StackFrame * getParent() const
It might return null.
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.