29 #include "llvm/ADT/ImmutableMap.h" 30 #include "llvm/ADT/Optional.h" 31 #include "llvm/Support/raw_ostream.h" 34 using namespace clang;
46 enum { Symbolic = 0x2 };
48 llvm::PointerIntPair<const MemRegion *, 2>
P;
54 : P(r, k | Symbolic), Data(reinterpret_cast<
uintptr_t>(Base)) {
55 assert(r && Base &&
"Must have known regions.");
56 assert(getConcreteOffsetRegion() == Base &&
"Failed to store base region");
60 explicit BindingKey(
const MemRegion *r, uint64_t offset,
Kind k)
61 : P(r, k), Data(offset) {
62 assert(r &&
"Must have known regions.");
63 assert(getOffset() == offset &&
"Failed to store offset");
64 assert((r == r->
getBaseRegion() || isa<ObjCIvarRegion>(r)) &&
"Not a base");
68 bool isDirect()
const {
return P.getInt() & Direct; }
69 bool hasSymbolicOffset()
const {
return P.getInt() & Symbolic; }
71 const MemRegion *getRegion()
const {
return P.getPointer(); }
72 uint64_t getOffset()
const {
73 assert(!hasSymbolicOffset());
77 const SubRegion *getConcreteOffsetRegion()
const {
78 assert(hasSymbolicOffset());
83 if (hasSymbolicOffset())
88 void Profile(llvm::FoldingSetNodeID&
ID)
const {
89 ID.AddPointer(P.getOpaqueValue());
96 if (P.getOpaqueValue() < X.P.getOpaqueValue())
98 if (P.getOpaqueValue() > X.P.getOpaqueValue())
100 return Data < X.Data;
104 return P.getOpaqueValue() == X.P.getOpaqueValue() &&
115 return BindingKey(cast<SubRegion>(R), cast<SubRegion>(RO.
getRegion()), k);
123 os <<
'(' << K.getRegion();
124 if (!K.hasSymbolicOffset())
125 os <<
',' << K.getOffset();
126 os <<
',' << (K.isDirect() ?
"direct" :
"default")
133 static const bool value =
true;
149 typedef llvm::ImmutableMap<const MemRegion *, ClusterBindings>
153 class RegionBindingsRef :
public llvm::ImmutableMapRef<const MemRegion *,
158 typedef llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>
162 const RegionBindings::TreeTy *T,
164 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(T, F),
165 CBFactory(&CBFactory) {}
168 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(
P),
169 CBFactory(&CBFactory) {}
171 RegionBindingsRef add(key_type_ref K, data_type_ref D)
const {
172 return RegionBindingsRef(static_cast<const ParentTy *>(
this)->add(K, D),
176 RegionBindingsRef
remove(key_type_ref K)
const {
177 return RegionBindingsRef(static_cast<const ParentTy *>(
this)->
remove(K),
181 RegionBindingsRef addBinding(BindingKey K,
SVal V)
const;
183 RegionBindingsRef addBinding(
const MemRegion *R,
184 BindingKey::Kind k,
SVal V)
const;
186 const SVal *lookup(BindingKey K)
const;
187 const SVal *lookup(
const MemRegion *R, BindingKey::Kind k)
const;
188 using llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>::lookup;
190 RegionBindingsRef removeBinding(BindingKey K);
192 RegionBindingsRef removeBinding(
const MemRegion *R,
195 RegionBindingsRef removeBinding(
const MemRegion *R) {
196 return removeBinding(R, BindingKey::Direct).
207 Store asStore()
const {
208 return asImmutableMap().getRootWithoutRetain();
211 void dump(raw_ostream &OS,
const char *nl)
const {
212 for (iterator I = begin(), E = end(); I != E; ++I) {
213 const ClusterBindings &Cluster = I.getData();
214 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
216 OS <<
' ' << CI.getKey() <<
" : " << CI.getData() << nl;
222 LLVM_DUMP_METHOD
void dump()
const {
dump(llvm::errs(),
"\n"); }
236 RegionBindingsRef RegionBindingsRef::addBinding(BindingKey K,
SVal V)
const {
237 const MemRegion *Base = K.getBaseRegion();
239 const ClusterBindings *ExistingCluster = lookup(Base);
240 ClusterBindings Cluster =
241 (ExistingCluster ? *ExistingCluster : CBFactory->getEmptyMap());
243 ClusterBindings NewCluster = CBFactory->add(Cluster, K, V);
244 return add(Base, NewCluster);
248 RegionBindingsRef RegionBindingsRef::addBinding(
const MemRegion *R,
254 const SVal *RegionBindingsRef::lookup(BindingKey K)
const {
255 const ClusterBindings *Cluster = lookup(K.getBaseRegion());
258 return Cluster->lookup(K);
262 BindingKey::Kind k)
const {
266 RegionBindingsRef RegionBindingsRef::removeBinding(BindingKey K) {
267 const MemRegion *Base = K.getBaseRegion();
268 const ClusterBindings *Cluster = lookup(Base);
272 ClusterBindings NewCluster = CBFactory->remove(*Cluster, K);
273 if (NewCluster.isEmpty())
275 return add(Base, NewCluster);
278 RegionBindingsRef RegionBindingsRef::removeBinding(
const MemRegion *R,
288 struct minimal_features_tag {};
289 struct maximal_features_tag {};
291 class RegionStoreFeatures {
294 RegionStoreFeatures(minimal_features_tag) :
295 SupportsFields(
false) {}
297 RegionStoreFeatures(maximal_features_tag) :
298 SupportsFields(
true) {}
300 void enableFields(
bool t) { SupportsFields = t; }
302 bool supportsFields()
const {
return SupportsFields; }
311 class invalidateRegionsWorker;
315 const RegionStoreFeatures Features;
320 typedef std::vector<SVal> SValListTy;
323 SValListTy> LazyBindingsMapTy;
324 LazyBindingsMapTy LazyBindingsMap;
334 unsigned SmallStructLimit;
338 void populateWorkList(invalidateRegionsWorker &W,
340 InvalidatedRegions *TopLevelRegions);
346 SmallStructLimit(0) {
347 if (
SubEngine *Eng = StateMgr.getOwningEngine()) {
358 RegionBindingsRef setImplicitDefaultValue(RegionBindingsConstRef B,
370 return StoreRef(RBFactory.getEmptyMap().getRootWithoutRetain(), *
this);
381 InvalidatedRegions *Invalidated);
385 const Expr *E,
unsigned Count,
390 InvalidatedRegions *Invalidated,
391 InvalidatedRegions *InvalidatedTopLevel)
override;
396 RegionBindingsRef removeSubRegionBindings(RegionBindingsConstRef B,
402 return StoreRef(bind(getRegionBindings(store), LV, V).asStore(), *
this);
405 RegionBindingsRef bind(RegionBindingsConstRef B,
Loc LV,
SVal V);
411 RegionBindingsRef B = getRegionBindings(store);
414 assert(!(B.getDefaultBinding(R) || B.getDirectBinding(R)) &&
415 "Double initialization!");
417 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *
this);
432 if (
const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
433 if (BR->getDecl()->isEmpty())
436 RegionBindingsRef B = getRegionBindings(store);
437 SVal V = svalBuilder.makeZeroVal(Ctx.CharTy);
438 B = removeSubRegionBindings(B, cast<SubRegion>(R));
440 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *
this);
459 RegionBindingsRef bindStruct(RegionBindingsConstRef B,
463 RegionBindingsRef bindVector(RegionBindingsConstRef B,
466 RegionBindingsRef bindArray(RegionBindingsConstRef B,
472 RegionBindingsRef bindAggregate(RegionBindingsConstRef B,
481 void incrementReferenceCount(
Store store)
override {
482 getRegionBindings(store).manualRetain();
488 void decrementReferenceCount(
Store store)
override {
489 getRegionBindings(store).manualRelease();
492 bool includedInBindings(
Store store,
const MemRegion *region)
const override;
508 return getBinding(getRegionBindings(S), L, T);
512 RegionBindingsRef B = getRegionBindings(S);
523 SVal getBindingForField(RegionBindingsConstRef B,
const FieldRegion *R);
527 SVal getBindingForVar(RegionBindingsConstRef B,
const VarRegion *R);
531 SVal getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
536 RegionBindingsRef LazyBinding);
552 Optional<SVal> getBindingForDerivedDefaultValue(RegionBindingsConstRef B,
561 std::pair<Store, const SubRegion *>
562 findLazyBinding(RegionBindingsConstRef B,
const SubRegion *R,
595 RegionBindingsRef getRegionBindings(
Store store)
const {
596 return RegionBindingsRef(CBFactory,
597 static_cast<const RegionBindings::TreeTy*>(store),
598 RBFactory.getTreeFactory());
601 void print(
Store store, raw_ostream &Out,
const char* nl,
602 const char *sep)
override;
604 void iterBindings(
Store store, BindingsHandler& f)
override {
605 RegionBindingsRef B = getRegionBindings(store);
606 for (RegionBindingsRef::iterator I = B.begin(), E = B.end(); I != E; ++I) {
607 const ClusterBindings &Cluster = I.getData();
608 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
610 const BindingKey &K = CI.getKey();
613 if (
const SubRegion *R = dyn_cast<SubRegion>(K.getRegion())) {
615 if (!f.HandleBinding(*
this, store, R, CI.getData()))
629 std::unique_ptr<StoreManager>
631 RegionStoreFeatures F = maximal_features_tag();
632 return llvm::make_unique<RegionStoreManager>(StMgr, F);
635 std::unique_ptr<StoreManager>
637 RegionStoreFeatures F = minimal_features_tag();
638 F.enableFields(
true);
639 return llvm::make_unique<RegionStoreManager>(StMgr, F);
659 template <
typename DERIVED>
660 class ClusterAnalysis {
662 typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
663 typedef const MemRegion * WorkListElement;
666 llvm::SmallPtrSet<const ClusterBindings *, 16> Visited;
670 RegionStoreManager &RM;
678 const ClusterBindings *getCluster(
const MemRegion *R) {
685 bool includeEntireMemorySpace(
const MemRegion *Base) {
695 RegionBindingsRef getRegionBindings()
const {
return B; }
698 return Visited.count(getCluster(R));
701 void GenerateClusters() {
703 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end();
707 const ClusterBindings &Cluster = RI.getData();
708 assert(!Cluster.isEmpty() &&
"Empty clusters should be removed");
709 static_cast<DERIVED*
>(
this)->VisitAddedToCluster(Base, Cluster);
713 if (static_cast<DERIVED*>(
this)->includeEntireMemorySpace(Base))
714 AddToWorkList(WorkListElement(Base), &Cluster);
718 bool AddToWorkList(WorkListElement E,
const ClusterBindings *C) {
719 if (C && !Visited.insert(C).second)
726 return static_cast<DERIVED*
>(
this)->AddToWorkList(R);
730 while (!WL.empty()) {
731 WorkListElement E = WL.pop_back_val();
734 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, getCluster(BaseR));
738 void VisitAddedToCluster(
const MemRegion *baseR,
const ClusterBindings &C) {}
739 void VisitCluster(
const MemRegion *baseR,
const ClusterBindings *C) {}
741 void VisitCluster(
const MemRegion *BaseR,
const ClusterBindings *C,
743 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, C);
752 bool RegionStoreManager::scanReachableSymbols(
Store S,
const MemRegion *R,
754 assert(R == R->
getBaseRegion() &&
"Should only be called for base regions");
755 RegionBindingsRef B = getRegionBindings(S);
756 const ClusterBindings *Cluster = B.lookup(R);
761 for (ClusterBindings::iterator RI = Cluster->begin(), RE = Cluster->end();
763 if (!Callbacks.
scan(RI.getData()))
777 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
779 const MemRegion *Base = K.getConcreteOffsetRegion();
783 if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R))
785 Fields.push_back(FR->getDecl());
787 R = cast<SubRegion>(R)->getSuperRegion();
792 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
797 FieldVector FieldsInBindingKey;
800 ptrdiff_t Delta = FieldsInBindingKey.size() - Fields.size();
802 return std::equal(FieldsInBindingKey.begin() + Delta,
803 FieldsInBindingKey.end(),
806 return std::equal(FieldsInBindingKey.begin(), FieldsInBindingKey.end(),
807 Fields.begin() - Delta);
823 bool IncludeAllDefaultBindings) {
824 FieldVector FieldsInSymbolicSubregions;
825 if (TopKey.hasSymbolicOffset()) {
827 Top = TopKey.getConcreteOffsetRegion();
832 uint64_t Length = UINT64_MAX;
836 const llvm::APSInt &ExtentInt = ExtentCI->getValue();
837 assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned());
840 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(Top)) {
841 if (FR->getDecl()->isBitField())
842 Length = FR->getDecl()->getBitWidthValue(SVB.
getContext());
845 for (ClusterBindings::iterator I = Cluster.begin(), E = Cluster.end();
847 BindingKey NextKey = I.getKey();
848 if (NextKey.getRegion() == TopKey.getRegion()) {
854 if (NextKey.getOffset() > TopKey.getOffset() &&
855 NextKey.getOffset() - TopKey.getOffset() < Length) {
858 Bindings.push_back(*I);
860 }
else if (NextKey.getOffset() == TopKey.getOffset()) {
867 if (IncludeAllDefaultBindings || NextKey.isDirect())
868 Bindings.push_back(*I);
871 }
else if (NextKey.hasSymbolicOffset()) {
872 const MemRegion *Base = NextKey.getConcreteOffsetRegion();
877 if (IncludeAllDefaultBindings || NextKey.isDirect())
879 Bindings.push_back(*I);
880 }
else if (
const SubRegion *BaseSR = dyn_cast<SubRegion>(Base)) {
883 if (BaseSR->isSubRegionOf(Top))
885 Bindings.push_back(*I);
894 const SubRegion *Top,
bool IncludeAllDefaultBindings) {
897 IncludeAllDefaultBindings);
901 RegionStoreManager::removeSubRegionBindings(RegionBindingsConstRef B,
904 const MemRegion *ClusterHead = TopKey.getBaseRegion();
906 if (Top == ClusterHead) {
908 return B.remove(Top);
911 const ClusterBindings *Cluster = B.lookup(ClusterHead);
915 if (TopKey.hasSymbolicOffset()) {
916 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
926 ClusterBindingsRef Result(*Cluster, CBFactory);
930 Result = Result.remove(I->first);
936 if (TopKey.hasSymbolicOffset()) {
937 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
942 if (Result.isEmpty())
943 return B.remove(ClusterHead);
944 return B.add(ClusterHead, Result.asImmutableMap());
948 class invalidateRegionsWorker :
public ClusterAnalysis<invalidateRegionsWorker>
958 invalidateRegionsWorker(RegionStoreManager &rm,
961 const Expr *ex,
unsigned count,
967 : ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b),
968 Ex(ex), Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r),
969 GlobalsFilter(GFK) {}
971 void VisitCluster(
const MemRegion *baseR,
const ClusterBindings *C);
972 void VisitBinding(
SVal V);
974 using ClusterAnalysis::AddToWorkList;
980 bool includeEntireMemorySpace(
const MemRegion *Base);
984 bool isInitiallyIncludedGlobalRegion(
const MemRegion *R);
988 bool invalidateRegionsWorker::AddToWorkList(
const MemRegion *R) {
989 bool doNotInvalidateSuperRegion = ITraits.hasTrait(
992 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
995 void invalidateRegionsWorker::VisitBinding(
SVal V) {
1009 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
1011 for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
1020 void invalidateRegionsWorker::VisitCluster(
const MemRegion *baseR,
1021 const ClusterBindings *C) {
1023 bool PreserveRegionsContents =
1024 ITraits.hasTrait(baseR,
1028 for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E; ++I)
1029 VisitBinding(I.getData());
1032 if (!PreserveRegionsContents)
1033 B = B.remove(baseR);
1040 BI = BR->referenced_vars_begin(), BE = BR->referenced_vars_end() ;
1042 const VarRegion *VR = BI.getCapturedRegion();
1055 if (
const MemRegion *LR = L->getAsRegion())
1065 IS.insert(SR->getSymbol());
1068 if (PreserveRegionsContents)
1073 Regions->push_back(baseR);
1075 if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
1079 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx, Ctx.IntTy, Count);
1090 if (isInitiallyIncludedGlobalRegion(baseR)) {
1097 if (T->isRecordType()) {
1106 if (
const ArrayType *AT = Ctx.getAsArrayType(T)) {
1107 bool doNotInvalidateSuperRegion = ITraits.hasTrait(
1111 if (doNotInvalidateSuperRegion) {
1118 NumElements = CAT->getSize().getZExtValue();
1120 goto conjure_default;
1121 QualType ElementTy = AT->getElementType();
1122 uint64_t ElemSize = Ctx.getTypeSize(ElementTy);
1129 AddToWorkList(SuperR);
1130 goto conjure_default;
1134 uint64_t UpperOffset = LowerOffset + *NumElements * ElemSize;
1135 bool UpperOverflow = UpperOffset < LowerOffset;
1140 goto conjure_default;
1142 const ClusterBindings *C = B.lookup(SuperR);
1144 goto conjure_default;
1146 for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E;
1148 const BindingKey &BK = I.getKey();
1155 ((*ROffset >= LowerOffset && *ROffset < UpperOffset) ||
1157 (*ROffset >= LowerOffset || *ROffset < UpperOffset)) ||
1158 (LowerOffset == UpperOffset && *ROffset == LowerOffset))) {
1159 B = B.removeBinding(I.getKey());
1162 SVal V = I.getData();
1164 if (R && isa<SymbolicRegion>(R))
1172 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
1173 AT->getElementType(), Count);
1181 B = B.addBinding(baseR, BindingKey::Direct, V);
1184 bool invalidateRegionsWorker::isInitiallyIncludedGlobalRegion(
1186 switch (GlobalsFilter) {
1189 case GFK_SystemOnly:
1195 llvm_unreachable(
"unknown globals filter");
1198 bool invalidateRegionsWorker::includeEntireMemorySpace(
const MemRegion *Base) {
1199 if (isInitiallyIncludedGlobalRegion(Base))
1203 return ITraits.hasTrait(MemSpace,
1212 RegionBindingsRef B,
1213 InvalidatedRegions *Invalidated) {
1217 SVal V = svalBuilder.conjureSymbolVal( (
const void*) GS, Ex, LCtx,
1221 B = B.removeBinding(GS)
1227 Invalidated->push_back(GS);
1232 void RegionStoreManager::populateWorkList(invalidateRegionsWorker &W,
1234 InvalidatedRegions *TopLevelRegions) {
1236 E = Values.end(); I != E; ++I) {
1241 const SValListTy &Vals = getInterestingValues(*LCS);
1243 for (SValListTy::const_iterator I = Vals.begin(),
1244 E = Vals.end(); I != E; ++I) {
1247 if (
const MemRegion *R = (*I).getAsRegion())
1254 if (TopLevelRegions)
1255 TopLevelRegions->push_back(R);
1263 RegionStoreManager::invalidateRegions(
Store store,
1265 const Expr *Ex,
unsigned Count,
1270 InvalidatedRegions *TopLevelRegions,
1271 InvalidatedRegions *Invalidated) {
1275 GlobalsFilter = GFK_SystemOnly;
1277 GlobalsFilter = GFK_All;
1279 GlobalsFilter = GFK_None;
1282 RegionBindingsRef B = getRegionBindings(store);
1283 invalidateRegionsWorker W(*
this, StateMgr, B, Ex, Count, LCtx, IS, ITraits,
1284 Invalidated, GlobalsFilter);
1287 W.GenerateClusters();
1290 populateWorkList(W, Values, TopLevelRegions);
1295 B = W.getRegionBindings();
1301 switch (GlobalsFilter) {
1303 B = invalidateGlobalRegion(MemRegion::GlobalInternalSpaceRegionKind,
1304 Ex, Count, LCtx, B, Invalidated);
1306 case GFK_SystemOnly:
1307 B = invalidateGlobalRegion(MemRegion::GlobalSystemSpaceRegionKind,
1308 Ex, Count, LCtx, B, Invalidated);
1314 return StoreRef(B.asStore(), *
this);
1325 SVal Size = cast<SubRegion>(R)->getExtent(svalBuilder);
1326 const llvm::APSInt *SizeInt = svalBuilder.getKnownValue(state, Size);
1332 if (Ctx.getAsVariableArrayType(EleTy)) {
1339 CharUnits EleSize = Ctx.getTypeSizeInChars(EleTy);
1344 return svalBuilder.makeIntVal(RegionSize / EleSize,
1345 svalBuilder.getArrayIndexType());
1367 NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex();
1375 SVal RegionStoreManager::getBinding(RegionBindingsConstRef B,
Loc L,
QualType T) {
1394 if (isa<BlockDataRegion>(MR)) {
1398 if (!isa<TypedValueRegion>(MR)) {
1400 if (
const TypedRegion *TR = dyn_cast<TypedRegion>(MR))
1402 else if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
1405 assert(!T.
isNull() &&
"Unable to auto-detect binding type!");
1406 assert(!T->
isVoidType() &&
"Attempting to dereference a void pointer!");
1407 MR = GetElementZeroRegion(cast<SubRegion>(MR), T);
1409 T = cast<TypedValueRegion>(MR)->getValueType();
1419 if (RTy->isAnyComplexType())
1430 if (RTy->isStructureOrClassType())
1431 return getBindingForStruct(B, R);
1434 if (RTy->isUnionType())
1435 return createLazyBinding(B, R);
1437 if (RTy->isArrayType()) {
1438 if (RTy->isConstantArrayType())
1439 return getBindingForArray(B, R);
1445 if (RTy->isVectorType())
1448 if (
const FieldRegion* FR = dyn_cast<FieldRegion>(R))
1449 return CastRetrievedVal(getBindingForField(B, FR), FR, T);
1457 return CastRetrievedVal(getBindingForElement(B, ER), ER, T);
1467 return CastRetrievedVal(getBindingForObjCIvar(B, IVR), IVR, T);
1470 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
1477 return CastRetrievedVal(getBindingForVar(B, VR), VR, T);
1480 const SVal *V = B.lookup(R, BindingKey::Direct);
1498 return svalBuilder.getRegionValueSymbolVal(R);
1504 RegionTy = TVR->getValueType();
1507 RegionTy = SR->getSymbol()->getType();
1521 const SubRegion *R,
bool AllowSubregionBindings) {
1533 if (!RegionTy.
isNull() &&
1535 QualType SourceRegionTy = LCV->getRegion()->getValueType();
1540 if (!AllowSubregionBindings) {
1546 if (Bindings.size() > 1)
1554 std::pair<Store, const SubRegion *>
1555 RegionStoreManager::findLazyBinding(RegionBindingsConstRef B,
1558 if (originalRegion != R) {
1561 return std::make_pair(V->getStore(), V->getRegion());
1564 typedef std::pair<Store, const SubRegion *> StoreRegionPair;
1565 StoreRegionPair Result = StoreRegionPair();
1568 Result = findLazyBinding(B, cast<SubRegion>(ER->getSuperRegion()),
1572 Result.second = MRMgr.getElementRegionWithSuper(ER, Result.second);
1574 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
1575 Result = findLazyBinding(B, cast<SubRegion>(FR->getSuperRegion()),
1579 Result.second = MRMgr.getFieldRegionWithSuper(FR, Result.second);
1582 dyn_cast<CXXBaseObjectRegion>(R)) {
1585 Result = findLazyBinding(B, cast<SubRegion>(BaseReg->getSuperRegion()),
1589 Result.second = MRMgr.getCXXBaseObjectRegionWithSuper(BaseReg,
1596 SVal RegionStoreManager::getBindingForElement(RegionBindingsConstRef B,
1609 if (
const StringRegion *StrR = dyn_cast<StringRegion>(superR)) {
1612 QualType T = Ctx.getAsArrayType(StrR->getValueType())->getElementType();
1619 int64_t i = CI->getValue().getSExtValue();
1630 return svalBuilder.makeIntVal(c, T);
1632 }
else if (
const VarRegion *VR = dyn_cast<VarRegion>(superR)) {
1634 const VarDecl *VD = VR->getDecl();
1638 if (
const auto *InitList = dyn_cast<InitListExpr>(Init)) {
1641 int64_t i = CI->getValue().getSExtValue();
1647 if (
auto CAT = Ctx.getAsConstantArrayType(VD->
getType()))
1648 if (CAT->getSize().sle(i))
1652 if (i >= InitList->getNumInits())
1655 if (
const Expr *ElemInit = InitList->getInit(i))
1665 if (isa<CodeTextRegion>(superR))
1681 dyn_cast_or_null<TypedValueRegion>(O.
getRegion())) {
1682 QualType baseT = baseR->getValueType();
1686 if (Ctx.getTypeSizeInChars(baseT) >= Ctx.getTypeSizeInChars(elemT)) {
1689 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1701 return getBindingForFieldOrElementCommon(B, R, R->
getElementType());
1704 SVal RegionStoreManager::getBindingForField(RegionBindingsConstRef B,
1721 if (
const auto *VR = dyn_cast<VarRegion>(superR)) {
1722 const VarDecl *VD = VR->getDecl();
1728 if (
const auto *InitList = dyn_cast<InitListExpr>(Init)) {
1729 if (Index < InitList->getNumInits()) {
1730 if (
const Expr *FieldInit = InitList->getInit(Index))
1734 return svalBuilder.makeZeroVal(Ty);
1739 return getBindingForFieldOrElementCommon(B, R, Ty);
1743 RegionStoreManager::getBindingForDerivedDefaultValue(RegionBindingsConstRef B,
1749 const SVal &val = D.getValue();
1751 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1754 return svalBuilder.makeZeroVal(Ty);
1765 llvm_unreachable(
"Unknown default value");
1771 SVal RegionStoreManager::getLazyBinding(
const SubRegion *LazyBindingRegion,
1772 RegionBindingsRef LazyBinding) {
1774 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(LazyBindingRegion))
1775 Result = getBindingForElement(LazyBinding, ER);
1777 Result = getBindingForField(LazyBinding,
1778 cast<FieldRegion>(LazyBindingRegion));
1801 RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
1809 Store lazyBindingStore =
nullptr;
1810 const SubRegion *lazyBindingRegion =
nullptr;
1811 std::tie(lazyBindingStore, lazyBindingRegion) = findLazyBinding(B, R, R);
1812 if (lazyBindingRegion)
1813 return getLazyBinding(lazyBindingRegion,
1814 getRegionBindings(lazyBindingStore));
1818 bool hasSymbolicIndex =
false;
1834 bool hasPartialLazyBinding =
false;
1839 if (
Optional<SVal> D = getBindingForDerivedDefaultValue(B, Base, R, Ty)) {
1841 hasPartialLazyBinding =
true;
1848 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(Base)) {
1849 NonLoc index = ER->getIndex();
1851 hasSymbolicIndex =
true;
1860 if (isa<ElementRegion>(R)) {
1865 if (typedSuperR->getValueType()->isVectorType())
1874 if (hasSymbolicIndex)
1877 if (!hasPartialLazyBinding)
1882 return svalBuilder.getRegionValueSymbolVal(R);
1885 SVal RegionStoreManager::getBindingForObjCIvar(RegionBindingsConstRef B,
1896 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1902 return getBindingForLazySymbol(R);
1905 SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B,
1917 if (isa<StackArgumentsSpaceRegion>(MS))
1918 return svalBuilder.getRegionValueSymbolVal(R);
1935 if (isa<UnknownSpaceRegion>(MS))
1936 return svalBuilder.getRegionValueSymbolVal(R);
1938 if (isa<GlobalsSpaceRegion>(MS)) {
1945 if (isa<StaticGlobalSpaceRegion>(MS))
1946 return svalBuilder.makeZeroVal(T);
1948 if (
Optional<SVal> V = getBindingForDerivedDefaultValue(B, MS, R, T)) {
1950 return V.getValue();
1953 return svalBuilder.getRegionValueSymbolVal(R);
1961 return svalBuilder.getRegionValueSymbolVal(R);
1964 const RegionStoreManager::SValListTy &
1967 LazyBindingsMapTy::iterator I = LazyBindingsMap.find(LCV.
getCVData());
1968 if (I != LazyBindingsMap.end())
1975 RegionBindingsRef B = getRegionBindings(LCV.
getStore());
1979 const ClusterBindings *Cluster = B.lookup(LazyR->getBaseRegion());
1981 return (LazyBindingsMap[LCV.
getCVData()] = std::move(List));
1995 const SValListTy &InnerList = getInterestingValues(*InnerLCV);
1996 List.insert(List.end(), InnerList.begin(), InnerList.end());
2003 return (LazyBindingsMap[LCV.
getCVData()] = std::move(List));
2006 NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B,
2012 return svalBuilder.makeLazyCompoundVal(
StoreRef(B.asStore(), *
this), R);
2019 return CRD->getNumBases() == 0;
2023 SVal RegionStoreManager::getBindingForStruct(RegionBindingsConstRef B,
2029 return createLazyBinding(B, R);
2032 SVal RegionStoreManager::getBindingForArray(RegionBindingsConstRef B,
2034 assert(Ctx.getAsConstantArrayType(R->
getValueType()) &&
2035 "Only constant array types can have compound bindings.");
2037 return createLazyBinding(B, R);
2040 bool RegionStoreManager::includedInBindings(
Store store,
2042 RegionBindingsRef B = getRegionBindings(store);
2046 if (B.lookup(region))
2050 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI) {
2051 const ClusterBindings &Cluster = RI.getData();
2052 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
2054 const SVal &D = CI.getData();
2070 if (
const MemRegion* R = LV->getRegion())
2071 return StoreRef(getRegionBindings(ST).removeBinding(R)
2073 .getRootWithoutRetain(),
2080 RegionStoreManager::bind(RegionBindingsConstRef B,
Loc L,
SVal V) {
2091 return bindArray(B, TR, V);
2093 return bindStruct(B, TR, V);
2095 return bindVector(B, TR, V);
2097 return bindAggregate(B, TR, V);
2103 QualType T = SR->getSymbol()->getType();
2107 R = GetElementZeroRegion(SR, T);
2110 assert((!isa<CXXThisRegion>(R) || !B.lookup(R)) &&
2111 "'this' pointer is not an l-value and is not assignable");
2114 RegionBindingsRef NewB = removeSubRegionBindings(B, cast<SubRegion>(R));
2119 RegionStoreManager::setImplicitDefaultValue(RegionBindingsConstRef B,
2125 V = svalBuilder.makeNull();
2127 V = svalBuilder.makeZeroVal(T);
2131 V = svalBuilder.makeZeroVal(Ctx.IntTy);
2146 RegionStoreManager::bindArray(RegionBindingsConstRef B,
2155 Size = CAT->getSize().getZExtValue();
2162 return bindAggregate(B, R, V);
2167 return bindAggregate(B, R, Init);
2177 RegionBindingsRef NewB(B);
2179 for (; Size.hasValue() ? i < Size.getValue() :
true ; ++i, ++VI) {
2184 const NonLoc &Idx = svalBuilder.makeArrayIndex(i);
2185 const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx);
2188 NewB = bindStruct(NewB, ER, *VI);
2190 NewB = bindArray(NewB, ER, *VI);
2198 if (!Size.hasValue() || i < Size.getValue())
2199 NewB = setImplicitDefaultValue(NewB, R, ElementTy);
2204 RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B,
2213 return bindAggregate(B, R, V);
2222 QualType ElemType = VT->getElementType();
2225 unsigned index = 0, numElements = VT->getNumElements();
2226 RegionBindingsRef NewB(B);
2228 for ( ; index != numElements ; ++index) {
2232 NonLoc Idx = svalBuilder.makeArrayIndex(index);
2233 const ElementRegion *ER = MRMgr.getElementRegion(ElemType, Idx, R, Ctx);
2236 NewB = bindArray(NewB, ER, *VI);
2238 NewB = bindStruct(NewB, ER, *VI);
2246 RegionStoreManager::tryBindSmallStruct(RegionBindingsConstRef B,
2252 if (
const CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(RD))
2253 if (Class->getNumBases() != 0 || Class->getNumVBases() != 0)
2256 for (
const auto *FD : RD->
fields()) {
2257 if (FD->isUnnamedBitfield())
2262 if (Fields.size() == SmallStructLimit)
2269 Fields.push_back(FD);
2272 RegionBindingsRef NewB = B;
2274 for (FieldVector::iterator I = Fields.begin(), E = Fields.end(); I != E; ++I){
2276 SVal V = getBindingForField(getRegionBindings(LCV.
getStore()), SourceFR);
2278 const FieldRegion *DestFR = MRMgr.getFieldRegion(*I, R);
2285 RegionBindingsRef RegionStoreManager::bindStruct(RegionBindingsConstRef B,
2288 if (!Features.supportsFields())
2297 if (!RD->isCompleteDefinition())
2305 return bindAggregate(B, R, V);
2308 return bindAggregate(B, R, V);
2320 RegionBindingsRef NewB(B);
2322 for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI) {
2328 if (FI->isUnnamedBitfield())
2332 const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
2335 NewB = bindArray(NewB, FR, *VI);
2337 NewB = bindStruct(NewB, FR, *VI);
2346 svalBuilder.makeIntVal(0,
false));
2353 RegionStoreManager::bindAggregate(RegionBindingsConstRef B,
2366 class removeDeadBindingsWorker :
2367 public ClusterAnalysis<removeDeadBindingsWorker> {
2373 removeDeadBindingsWorker(RegionStoreManager &rm,
2377 : ClusterAnalysis<removeDeadBindingsWorker>(rm, stateMgr, b),
2378 SymReaper(symReaper), CurrentLCtx(LCtx) {}
2381 void VisitAddedToCluster(
const MemRegion *baseR,
const ClusterBindings &C);
2382 void VisitCluster(
const MemRegion *baseR,
const ClusterBindings *C);
2383 using ClusterAnalysis<removeDeadBindingsWorker>::VisitCluster;
2385 using ClusterAnalysis::AddToWorkList;
2389 bool UpdatePostponed();
2390 void VisitBinding(
SVal V);
2394 bool removeDeadBindingsWorker::AddToWorkList(
const MemRegion *R) {
2396 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
2399 void removeDeadBindingsWorker::VisitAddedToCluster(
const MemRegion *baseR,
2400 const ClusterBindings &C) {
2402 if (
const VarRegion *VR = dyn_cast<VarRegion>(baseR)) {
2403 if (SymReaper.isLive(VR))
2404 AddToWorkList(baseR, &C);
2409 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
2410 if (SymReaper.isLive(SR->getSymbol()))
2411 AddToWorkList(SR, &C);
2413 Postponed.push_back(SR);
2418 if (isa<NonStaticGlobalSpaceRegion>(baseR)) {
2419 AddToWorkList(baseR, &C);
2424 if (
const CXXThisRegion *TR = dyn_cast<CXXThisRegion>(baseR)) {
2426 cast<StackArgumentsSpaceRegion>(TR->getSuperRegion());
2429 (RegCtx == CurrentLCtx || RegCtx->isParentOf(CurrentLCtx)))
2430 AddToWorkList(TR, &C);
2434 void removeDeadBindingsWorker::VisitCluster(
const MemRegion *baseR,
2435 const ClusterBindings *C) {
2441 if (
const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(baseR))
2442 SymReaper.markLive(SymR->getSymbol());
2444 for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E; ++I) {
2446 SymReaper.markElementIndicesLive(I.getKey().getRegion());
2448 VisitBinding(I.getData());
2452 void removeDeadBindingsWorker::VisitBinding(
SVal V) {
2457 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
2459 for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
2470 SymReaper.markLive(R);
2475 E = BR->referenced_vars_end();
2476 for ( ; I != E; ++I)
2485 SymReaper.markLive(*SI);
2488 bool removeDeadBindingsWorker::UpdatePostponed() {
2491 bool changed =
false;
2494 I = Postponed.begin(), E = Postponed.end() ; I != E ; ++I) {
2496 if (SymReaper.isLive(SR->getSymbol())) {
2497 changed |= AddToWorkList(SR);
2506 StoreRef RegionStoreManager::removeDeadBindings(
Store store,
2509 RegionBindingsRef B = getRegionBindings(store);
2510 removeDeadBindingsWorker W(*
this, StateMgr, B, SymReaper, LCtx);
2511 W.GenerateClusters();
2516 W.AddToWorkList(*I);
2519 do W.RunWorkList();
while (W.UpdatePostponed());
2524 for (RegionBindingsRef::iterator I = B.begin(), E = B.end(); I != E; ++I) {
2528 if (W.isVisited(Base))
2538 const ClusterBindings &Cluster = I.getData();
2539 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
2541 SVal X = CI.getData();
2543 for (; SI != SE; ++SI)
2548 return StoreRef(B.asStore(), *
this);
2555 void RegionStoreManager::print(
Store store, raw_ostream &OS,
2556 const char* nl,
const char *sep) {
2557 RegionBindingsRef B = getRegionBindings(store);
2558 OS <<
"Store (direct and default bindings), "
TypedValueRegion - An abstract class representing regions having a typed value.
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
static void getSymbolicOffsetFields(BindingKey K, FieldVector &Fields)
bool operator==(CanQual< T > x, CanQual< U > y)
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Information about invalidation for a particular region/symbol.
bool maybeDead(SymbolRef sym)
If a symbol is known to be live, marks the symbol as live.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
virtual QualType getValueType() const =0
static bool isRecordEmpty(const RecordDecl *RD)
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const MemRegion * getRegion() const
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
static Optional< nonloc::LazyCompoundVal > getExistingLazyBinding(SValBuilder &SVB, RegionBindingsConstRef B, const SubRegion *R, bool AllowSubregionBindings)
Checks to see if store B has a lazy binding for region R.
Value representing integer constant.
A utility class that visits the reachable symbols using a custom SymbolVisitor.
QualType getElementType() const
Represents a variable declaration or definition.
const T * getAs() const
Member-template getAs<specific type>'.
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
QualType getElementType() const
std::unique_ptr< StoreManager > CreateFieldsOnlyRegionStoreManager(ProgramStateManager &StMgr)
CXXThisRegion - Represents the region for the implicit 'this' parameter in a call to a C++ method...
const MemRegion * getSuperRegion() const
Represents a struct/union/class.
llvm::ImmutableMap< BindingKey, SVal > ClusterBindings
SmallVector< const FieldDecl *, 8 > FieldVector
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
llvm::ImmutableList< SVal >::iterator iterator
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
field_range fields() const
const FieldDecl * getDecl() const
Represents a member of a struct/union/class.
static bool canSymbolicate(QualType T)
bool isReferenceType() const
SValBuilder & getSValBuilder()
i32 captured_struct **param SharedsTy A type which contains references the shared variables *param Shareds Context with the list of shared variables from the p *TaskFunction *param Data Additional data for task generation like final * state
virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const
getExtent - Returns the size of the region in bytes.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
static bool isLocType(QualType T)
BlockDataRegion - A region that represents a block instance.
unsigned getLength() const
CharUnits - This is an opaque type for sizes expressed in character units.
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
RegionSetTy::const_iterator region_iterator
llvm::ImmutableMap< const MemRegion *, ClusterBindings > RegionBindings
const LazyCompoundValData * getCVData() const
SymExpr::symbol_iterator symbol_end() const
bool isScalarType() const
QualType getValueType() const override
Represent a region's offset within the top level base region.
const MemSpaceRegion * getMemorySpace() const
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
std::unique_ptr< StoreManager > CreateRegionStoreManager(ProgramStateManager &StMgr)
const VarRegion * getCapturedRegion() const
static bool isCompatibleWithFields(BindingKey K, const FieldVector &Fields)
When applied to a MemSpaceRegion, indicates the entire memory space should be invalidated.
SymbolicRegion - A special, "non-concrete" region.
static void collectSubRegionBindings(SmallVectorImpl< BindingPair > &Bindings, SValBuilder &SVB, const ClusterBindings &Cluster, const SubRegion *Top, BindingKey TopKey, bool IncludeAllDefaultBindings)
Collects all bindings in Cluster that may refer to bindings within Top.
Expr - This represents one expression.
GlobalsFilterKind
Used to determine which global regions are automatically included in the initial worklist of a Cluste...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
const T * castAs() const
Member-template castAs<specific type>.
bool isInSystemHeader() const
Returns true if the callee is known to be from a system header.
uint32_t getCodeUnit(size_t i) const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Represents a GCC generic vector type.
float __ovld __cnfn length(float p)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
llvm::ImmutableMapRef< BindingKey, SVal > ClusterBindingsRef
const StackFrameContext * getStackFrame() const
const VarDecl * getDecl() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
virtual bool isBoundable() const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isVoidPointerType() const
bool isStructureOrClassType() const
bool scan(nonloc::LazyCompoundVal val)
llvm::BumpPtrAllocator & getAllocator()
const MemRegion * getAsRegion() const
static QualType getUnderlyingType(const SubRegion *R)
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set...
bool isSubRegionOf(const MemRegion *R) const override
Check if the region is a subregion of the given region.
ASTContext & getContext()
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
bool isAnyPointerType() const
A class responsible for cleaning up unused symbols.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
region_iterator region_end() const
bool isVectorType() const
Tells that a region's contents is not changed.
RegionRawOffset getAsArrayOffset() const
Compute the offset within the array. The array might also be a subobject.
__PTRDIFF_TYPE__ ptrdiff_t
A signed integer type that is the result of subtracting two pointers.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Dataflow Directional Tag Classes.
raw_ostream & operator<<(raw_ostream &Out, const CheckerBase &Checker)
Dump checker name to stream.
bool isZeroConstant() const
const void * getStore() const
const MemRegion * getRegion() const
const Expr * getInit() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
region_iterator region_begin() const
Represents symbolic expression that isn't a location.
Represents an abstract call to a function or method along a particular path.
ASTContext & getContext()
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
SubRegion - A region that subsets another larger region.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
int64_t getOffset() const
std::pair< BindingKey, SVal > BindingPair
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
static bool isUnionField(const FieldRegion *FR)
Represents a C++ struct/union/class.
const TypedValueRegion * getRegion() const
const MemRegion * getBaseRegion() const
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
StringRegion - Region associated with a StringLiteral.
ElementRegin is used to represent both array elements and casts.
SymExpr::symbol_iterator symbol_begin() const
static llvm::ImmutableListFactory< const FieldRegion * > Factory
int getOptionAsInteger(StringRef Name, int DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
Interprets an option's string value as an integer value.
const RegionBindingsRef & RegionBindingsConstRef
bool hasStackNonParametersStorage() const
Represents the canonical version of C arrays with a specified constant size.
bool hasSymbolicOffset() const
bool isUnknownOrUndef() const
TypedRegion - An abstract class representing regions that are typed.
Iterator over symbols that the current symbol depends on.