31 #include "llvm/ADT/ImmutableMap.h" 32 #include "llvm/ADT/Optional.h" 33 #include "llvm/Support/raw_ostream.h" 36 using namespace clang;
48 enum { Symbolic = 0x2 };
50 llvm::PointerIntPair<const MemRegion *, 2>
P;
55 explicit BindingKey(
const SubRegion *r,
const SubRegion *
Base,
Kind k)
57 assert(r &&
Base &&
"Must have known regions.");
58 assert(getConcreteOffsetRegion() ==
Base &&
"Failed to store base region");
62 explicit BindingKey(
const MemRegion *r, uint64_t offset,
Kind k)
63 :
P(r, k), Data(offset) {
64 assert(r &&
"Must have known regions.");
65 assert(getOffset() == offset &&
"Failed to store offset");
66 assert((r == r->getBaseRegion() || isa<ObjCIvarRegion>(r) ||
67 isa <CXXDerivedObjectRegion>(r)) &&
72 bool isDirect()
const {
return P.getInt() & Direct; }
73 bool hasSymbolicOffset()
const {
return P.getInt() & Symbolic; }
75 const MemRegion *getRegion()
const {
return P.getPointer(); }
76 uint64_t getOffset()
const {
77 assert(!hasSymbolicOffset());
81 const SubRegion *getConcreteOffsetRegion()
const {
82 assert(hasSymbolicOffset());
83 return reinterpret_cast<const SubRegion *>(static_cast<uintptr_t>(Data));
86 const MemRegion *getBaseRegion()
const {
87 if (hasSymbolicOffset())
88 return getConcreteOffsetRegion()->getBaseRegion();
89 return getRegion()->getBaseRegion();
92 void Profile(llvm::FoldingSetNodeID&
ID)
const {
93 ID.AddPointer(
P.getOpaqueValue());
97 static BindingKey
Make(
const MemRegion *R,
Kind k);
100 if (
P.getOpaqueValue() <
X.P.getOpaqueValue())
102 if (
P.getOpaqueValue() >
X.P.getOpaqueValue())
104 return Data <
X.Data;
108 return P.getOpaqueValue() ==
X.P.getOpaqueValue() &&
112 LLVM_DUMP_METHOD
void dump()
const;
117 const RegionOffset &RO = R->getAsOffset();
118 if (RO.hasSymbolicOffset())
119 return BindingKey(cast<SubRegion>(R), cast<SubRegion>(RO.getRegion()), k);
121 return BindingKey(RO.getRegion(), RO.getOffset(), k);
125 static inline raw_ostream &
operator<<(raw_ostream &Out, BindingKey K) {
126 Out <<
"\"kind\": \"" << (K.isDirect() ?
"Direct" :
"Default")
127 <<
"\", \"offset\": ";
129 if (!K.hasSymbolicOffset())
130 Out << K.getOffset();
139 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 151 typedef llvm::ImmutableMap<const MemRegion *, ClusterBindings>
155 class RegionBindingsRef :
public llvm::ImmutableMapRef<const MemRegion *,
157 ClusterBindings::Factory *CBFactory;
171 typedef llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>
174 RegionBindingsRef(ClusterBindings::Factory &CBFactory,
175 const RegionBindings::TreeTy *T,
176 RegionBindings::TreeTy::Factory *F,
178 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(T, F),
179 CBFactory(&CBFactory), IsMainAnalysis(IsMainAnalysis) {}
181 RegionBindingsRef(
const ParentTy &
P,
182 ClusterBindings::Factory &CBFactory,
184 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(
P),
185 CBFactory(&CBFactory), IsMainAnalysis(IsMainAnalysis) {}
187 RegionBindingsRef add(key_type_ref K, data_type_ref D)
const {
188 return RegionBindingsRef(static_cast<const ParentTy *>(
this)->add(K, D),
189 *CBFactory, IsMainAnalysis);
192 RegionBindingsRef
remove(key_type_ref K)
const {
193 return RegionBindingsRef(static_cast<const ParentTy *>(
this)->
remove(K),
194 *CBFactory, IsMainAnalysis);
197 RegionBindingsRef addBinding(BindingKey K, SVal
V)
const;
199 RegionBindingsRef addBinding(
const MemRegion *R,
200 BindingKey::Kind k, SVal
V)
const;
202 const SVal *lookup(BindingKey K)
const;
203 const SVal *lookup(
const MemRegion *R, BindingKey::Kind k)
const;
204 using llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>::lookup;
206 RegionBindingsRef removeBinding(BindingKey K);
208 RegionBindingsRef removeBinding(
const MemRegion *R,
211 RegionBindingsRef removeBinding(
const MemRegion *R) {
212 return removeBinding(R, BindingKey::Direct).
223 Store asStore()
const {
224 llvm::PointerIntPair<Store, 1, bool> Ptr = {
225 asImmutableMap().getRootWithoutRetain(), IsMainAnalysis};
226 return reinterpret_cast<Store>(Ptr.getOpaqueValue());
229 bool isMainAnalysis()
const {
230 return IsMainAnalysis;
233 void printJson(raw_ostream &Out,
const char *NL =
"\n",
234 unsigned int Space = 0,
bool IsDot =
false)
const {
235 for (iterator I = begin(); I != end(); ++I) {
238 <<
"{ \"cluster\": \"" << I.getKey() <<
"\", \"pointer\": \"" 239 << (
const void *)I.getKey() <<
"\", \"items\": [" << NL;
243 for (ClusterBindings::iterator CI = CB.begin(); CI != CB.end(); ++CI) {
244 Indent(Out, Space, IsDot) <<
"{ " << CI.getKey() <<
", \"value\": ";
245 CI.getData().printJson(Out,
true);
247 if (std::next(CI) != CB.end())
253 Indent(Out, Space, IsDot) <<
"]}";
254 if (std::next(I) != end())
260 LLVM_DUMP_METHOD
void dump()
const { printJson(llvm::errs()); }
266 Optional<SVal> RegionBindingsRef::getDirectBinding(
const MemRegion *R)
const {
270 Optional<SVal> RegionBindingsRef::getDefaultBinding(
const MemRegion *R)
const {
274 RegionBindingsRef RegionBindingsRef::addBinding(BindingKey K, SVal
V)
const {
275 const MemRegion *
Base = K.getBaseRegion();
279 (ExistingCluster ? *ExistingCluster : CBFactory->getEmptyMap());
282 return add(
Base, NewCluster);
286 RegionBindingsRef RegionBindingsRef::addBinding(
const MemRegion *R,
292 const SVal *RegionBindingsRef::lookup(BindingKey K)
const {
296 return Cluster->lookup(K);
299 const SVal *RegionBindingsRef::lookup(
const MemRegion *R,
300 BindingKey::Kind k)
const {
304 RegionBindingsRef RegionBindingsRef::removeBinding(BindingKey K) {
305 const MemRegion *
Base = K.getBaseRegion();
311 if (NewCluster.isEmpty())
313 return add(
Base, NewCluster);
316 RegionBindingsRef RegionBindingsRef::removeBinding(
const MemRegion *R,
326 struct minimal_features_tag {};
327 struct maximal_features_tag {};
329 class RegionStoreFeatures {
332 RegionStoreFeatures(minimal_features_tag) :
333 SupportsFields(
false) {}
335 RegionStoreFeatures(maximal_features_tag) :
336 SupportsFields(
true) {}
338 void enableFields(
bool t) { SupportsFields = t; }
340 bool supportsFields()
const {
return SupportsFields; }
349 class InvalidateRegionsWorker;
351 class RegionStoreManager :
public StoreManager {
353 const RegionStoreFeatures Features;
355 RegionBindings::Factory RBFactory;
356 mutable ClusterBindings::Factory CBFactory;
358 typedef std::vector<SVal> SValListTy;
360 typedef llvm::DenseMap<
const LazyCompoundValData *,
361 SValListTy> LazyBindingsMapTy;
362 LazyBindingsMapTy LazyBindingsMap;
372 unsigned SmallStructLimit;
376 void populateWorkList(InvalidateRegionsWorker &W,
378 InvalidatedRegions *TopLevelRegions);
381 RegionStoreManager(ProgramStateManager& mgr,
const RegionStoreFeatures &f)
382 : StoreManager(mgr), Features(f),
383 RBFactory(mgr.getAllocator()), CBFactory(mgr.getAllocator()),
384 SmallStructLimit(0) {
385 ExprEngine &Eng = StateMgr.getOwningEngine();
387 SmallStructLimit = Options.RegionStoreSmallStructLimit;
403 SVal ArrayToPointer(Loc Array,
QualType ElementTy)
override;
408 bool IsMainAnalysis =
false;
409 if (
const auto *FD = dyn_cast<FunctionDecl>(InitLoc->
getDecl()))
410 IsMainAnalysis = FD->isMain() && !Ctx.getLangOpts().CPlusPlus;
411 return StoreRef(RegionBindingsRef(
412 RegionBindingsRef::ParentTy(RBFactory.getEmptyMap(), RBFactory),
413 CBFactory, IsMainAnalysis).asStore(), *
this);
424 InvalidatedRegions *Invalidated);
426 StoreRef invalidateRegions(
Store store,
428 const Expr *E,
unsigned Count,
430 const CallEvent *Call,
432 RegionAndSymbolInvalidationTraits &ITraits,
433 InvalidatedRegions *Invalidated,
434 InvalidatedRegions *InvalidatedTopLevel)
override;
436 bool scanReachableSymbols(
Store S,
const MemRegion *R,
437 ScanReachableSymbols &Callbacks)
override;
444 StoreRef Bind(
Store store, Loc LV, SVal
V)
override {
445 return StoreRef(bind(getRegionBindings(store), LV,
V).asStore(), *
this);
452 StoreRef BindDefaultInitial(
Store store,
const MemRegion *R,
454 RegionBindingsRef B = getRegionBindings(store);
457 assert(!(B.getDefaultBinding(R) || B.getDirectBinding(R)) &&
458 "Double initialization!");
460 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *
this);
465 StoreRef BindDefaultZero(
Store store,
const MemRegion *R)
override {
475 if (
const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
476 if (BR->getDecl()->isEmpty())
477 return StoreRef(store, *
this);
479 RegionBindingsRef B = getRegionBindings(store);
480 SVal
V = svalBuilder.makeZeroVal(Ctx.CharTy);
481 B = removeSubRegionBindings(B, cast<SubRegion>(R));
483 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *
this);
497 const TypedValueRegion *R,
499 nonloc::LazyCompoundVal LCV);
503 const TypedValueRegion* R, SVal
V);
507 const TypedValueRegion* R, SVal
V);
510 const TypedValueRegion* R,
516 const TypedRegion *R,
522 StoreRef killBinding(
Store ST, Loc L)
override;
524 void incrementReferenceCount(
Store store)
override {
525 getRegionBindings(store).manualRetain();
531 void decrementReferenceCount(
Store store)
override {
532 getRegionBindings(store).manualRelease();
535 bool includedInBindings(
Store store,
const MemRegion *region)
const override;
551 return getBinding(getRegionBindings(S), L, T);
555 RegionBindingsRef B = getRegionBindings(S);
559 return B.getDefaultBinding(R->getBaseRegion());
572 SVal getBindingForLazySymbol(
const TypedValueRegion *R);
575 const TypedValueRegion *R,
578 SVal getLazyBinding(
const SubRegion *LazyBindingRegion,
579 RegionBindingsRef LazyBinding);
596 const MemRegion *superR,
597 const TypedValueRegion *R,
604 std::pair<Store, const SubRegion *>
606 const SubRegion *originalRegion);
614 const SValListTy &getInterestingValues(nonloc::LazyCompoundVal LCV);
623 SymbolReaper& SymReaper)
override;
629 RegionBindingsRef getRegionBindings(
Store store)
const {
630 llvm::PointerIntPair<Store, 1, bool> Ptr;
631 Ptr.setFromOpaqueValue(const_cast<void *>(store));
632 return RegionBindingsRef(
634 static_cast<const RegionBindings::TreeTy *>(Ptr.getPointer()),
635 RBFactory.getTreeFactory(),
639 void printJson(raw_ostream &Out,
Store S,
const char *NL =
"\n",
640 unsigned int Space = 0,
bool IsDot =
false)
const override;
642 void iterBindings(
Store store, BindingsHandler& f)
override {
643 RegionBindingsRef B = getRegionBindings(store);
644 for (RegionBindingsRef::iterator I = B.begin(), E = B.end(); I != E; ++I) {
646 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
648 const BindingKey &K = CI.getKey();
651 if (
const SubRegion *R = dyn_cast<SubRegion>(K.getRegion())) {
653 if (!f.HandleBinding(*
this, store, R, CI.getData()))
667 std::unique_ptr<StoreManager>
669 RegionStoreFeatures F = maximal_features_tag();
670 return std::make_unique<RegionStoreManager>(StMgr, F);
673 std::unique_ptr<StoreManager>
675 RegionStoreFeatures F = minimal_features_tag();
676 F.enableFields(
true);
677 return std::make_unique<RegionStoreManager>(StMgr, F);
697 template <
typename DERIVED>
698 class ClusterAnalysis {
700 typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
701 typedef const MemRegion * WorkListElement;
708 RegionStoreManager &RM;
710 SValBuilder &svalBuilder;
723 bool includeEntireMemorySpace(
const MemRegion *
Base) {
728 ClusterAnalysis(RegionStoreManager &rm, ProgramStateManager &StateMgr,
730 : RM(rm), Ctx(StateMgr.getContext()),
731 svalBuilder(StateMgr.getSValBuilder()), B(
std::move(
b)) {}
733 RegionBindingsRef getRegionBindings()
const {
return B; }
735 bool isVisited(
const MemRegion *R) {
736 return Visited.count(getCluster(R));
739 void GenerateClusters() {
741 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end();
743 const MemRegion *
Base = RI.getKey();
746 assert(!Cluster.isEmpty() &&
"Empty clusters should be removed");
747 static_cast<DERIVED*>(
this)->VisitAddedToCluster(
Base, Cluster);
751 if (static_cast<DERIVED*>(
this)->includeEntireMemorySpace(
Base))
752 AddToWorkList(WorkListElement(
Base), &Cluster);
757 if (C && !Visited.insert(C).second)
763 bool AddToWorkList(
const MemRegion *R) {
764 return static_cast<DERIVED*>(
this)->AddToWorkList(R);
768 while (!WL.empty()) {
769 WorkListElement E = WL.pop_back_val();
770 const MemRegion *BaseR = E;
772 static_cast<DERIVED*>(
this)->VisitCluster(BaseR, getCluster(BaseR));
776 void VisitAddedToCluster(
const MemRegion *baseR,
const ClusterBindings &C) {}
781 static_cast<DERIVED*>(
this)->VisitCluster(BaseR, C);
790 bool RegionStoreManager::scanReachableSymbols(
Store S,
const MemRegion *R,
791 ScanReachableSymbols &Callbacks) {
792 assert(R == R->getBaseRegion() &&
"Should only be called for base regions");
793 RegionBindingsRef B = getRegionBindings(S);
799 for (ClusterBindings::iterator RI = Cluster->begin(), RE = Cluster->end();
801 if (!Callbacks.scan(RI.getData()))
809 return FR->getDecl()->getParent()->isUnion();
815 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
817 const MemRegion *
Base = K.getConcreteOffsetRegion();
818 const MemRegion *R = K.getRegion();
821 if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R))
823 Fields.push_back(FR->getDecl());
825 R = cast<SubRegion>(R)->getSuperRegion();
830 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
838 ptrdiff_t Delta = FieldsInBindingKey.size() - Fields.size();
840 return std::equal(FieldsInBindingKey.begin() + Delta,
841 FieldsInBindingKey.end(),
844 return std::equal(FieldsInBindingKey.begin(), FieldsInBindingKey.end(),
845 Fields.begin() - Delta);
860 const SubRegion *Top, BindingKey TopKey,
861 bool IncludeAllDefaultBindings) {
863 if (TopKey.hasSymbolicOffset()) {
865 Top = TopKey.getConcreteOffsetRegion();
870 uint64_t Length = UINT64_MAX;
871 SVal Extent = Top->getMemRegionManager().getStaticSize(Top, SVB);
873 Extent.getAs<nonloc::ConcreteInt>()) {
875 assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned());
877 Length = ExtentInt.getLimitedValue() * SVB.getContext().getCharWidth();
878 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(Top)) {
879 if (FR->getDecl()->isBitField())
880 Length = FR->getDecl()->getBitWidthValue(SVB.getContext());
883 for (ClusterBindings::iterator I = Cluster.begin(), E = Cluster.end();
885 BindingKey NextKey = I.getKey();
886 if (NextKey.getRegion() == TopKey.getRegion()) {
892 if (NextKey.getOffset() > TopKey.getOffset() &&
893 NextKey.getOffset() - TopKey.getOffset() < Length) {
896 Bindings.push_back(*I);
898 }
else if (NextKey.getOffset() == TopKey.getOffset()) {
905 if (IncludeAllDefaultBindings || NextKey.isDirect())
906 Bindings.push_back(*I);
909 }
else if (NextKey.hasSymbolicOffset()) {
910 const MemRegion *
Base = NextKey.getConcreteOffsetRegion();
911 if (Top->isSubRegionOf(
Base) && Top !=
Base) {
915 if (IncludeAllDefaultBindings || NextKey.isDirect())
917 Bindings.push_back(*I);
918 }
else if (
const SubRegion *BaseSR = dyn_cast<SubRegion>(
Base)) {
921 if (BaseSR->isSubRegionOf(Top))
923 Bindings.push_back(*I);
932 const SubRegion *Top,
bool IncludeAllDefaultBindings) {
935 IncludeAllDefaultBindings);
940 const SubRegion *Top) {
942 const MemRegion *ClusterHead = TopKey.getBaseRegion();
944 if (Top == ClusterHead) {
946 return B.remove(Top);
953 if (TopKey.hasSymbolicOffset()) {
954 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
968 Result = Result.remove(I->first);
974 if (TopKey.hasSymbolicOffset()) {
975 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
980 if (Result.isEmpty())
981 return B.remove(ClusterHead);
982 return B.add(ClusterHead, Result.asImmutableMap());
986 class InvalidateRegionsWorker :
public ClusterAnalysis<InvalidateRegionsWorker>
992 RegionAndSymbolInvalidationTraits &ITraits;
996 InvalidateRegionsWorker(RegionStoreManager &rm,
997 ProgramStateManager &stateMgr,
999 const Expr *ex,
unsigned count,
1002 RegionAndSymbolInvalidationTraits &ITraitsIn,
1005 : ClusterAnalysis<InvalidateRegionsWorker>(rm, stateMgr,
b),
1006 Ex(ex), Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r),
1007 GlobalsFilter(GFK) {}
1010 void VisitBinding(SVal
V);
1012 using ClusterAnalysis::AddToWorkList;
1014 bool AddToWorkList(
const MemRegion *R);
1018 bool includeEntireMemorySpace(
const MemRegion *
Base);
1022 bool isInitiallyIncludedGlobalRegion(
const MemRegion *R);
1026 bool InvalidateRegionsWorker::AddToWorkList(
const MemRegion *R) {
1027 bool doNotInvalidateSuperRegion = ITraits.hasTrait(
1029 const MemRegion *BaseR = doNotInvalidateSuperRegion ? R : R->getBaseRegion();
1030 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
1033 void InvalidateRegionsWorker::VisitBinding(SVal
V) {
1038 if (
const MemRegion *R =
V.getAsRegion()) {
1045 V.getAs<nonloc::LazyCompoundVal>()) {
1047 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
1049 for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
1058 void InvalidateRegionsWorker::VisitCluster(
const MemRegion *baseR,
1061 bool PreserveRegionsContents =
1062 ITraits.hasTrait(baseR,
1066 for (ClusterBindings::iterator I =
C->begin(), E =
C->end(); I != E; ++I)
1067 VisitBinding(I.getData());
1070 if (!PreserveRegionsContents)
1071 B = B.remove(baseR);
1074 if (
const auto *TO = dyn_cast<TypedValueRegion>(baseR)) {
1075 if (
const auto *RD = TO->getValueType()->getAsCXXRecordDecl()) {
1080 if (RD->isLambda() && RD->getLambdaCallOperator()->getBody()) {
1081 using namespace ast_matchers;
1083 const char *DeclBind =
"DeclBind";
1085 to(
varDecl(hasStaticStorageDuration()).bind(DeclBind)))));
1087 match(RefToStatic, *RD->getLambdaCallOperator()->getBody(),
1088 RD->getASTContext());
1091 auto *VD = Match.getNodeAs<
VarDecl>(DeclBind);
1092 const VarRegion *ToInvalidate =
1093 RM.getRegionManager().getVarRegion(VD, LCtx);
1094 AddToWorkList(ToInvalidate);
1102 if (
const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(baseR)) {
1103 for (BlockDataRegion::referenced_vars_iterator
1104 BI = BR->referenced_vars_begin(), BE = BR->referenced_vars_end() ;
1106 const VarRegion *VR = BI.getCapturedRegion();
1107 const VarDecl *VD = VR->getDecl();
1117 SVal
V = RM.getBinding(B, loc::MemRegionVal(VR));
1119 if (
const MemRegion *LR = L->getAsRegion())
1128 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
1129 IS.insert(SR->getSymbol());
1132 if (PreserveRegionsContents)
1137 Regions->push_back(baseR);
1139 if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
1142 DefinedOrUnknownSVal
V =
1143 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx, Ctx.
IntTy, Count);
1148 if (!baseR->isBoundable())
1151 const TypedValueRegion *TR = cast<TypedValueRegion>(baseR);
1154 if (isInitiallyIncludedGlobalRegion(baseR)) {
1164 DefinedOrUnknownSVal
V = svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
1171 bool doNotInvalidateSuperRegion = ITraits.hasTrait(
1175 if (doNotInvalidateSuperRegion) {
1182 NumElements = CAT->getSize().getZExtValue();
1184 goto conjure_default;
1185 QualType ElementTy = AT->getElementType();
1187 const RegionOffset &RO = baseR->getAsOffset();
1188 const MemRegion *SuperR = baseR->getBaseRegion();
1189 if (RO.hasSymbolicOffset()) {
1193 AddToWorkList(SuperR);
1194 goto conjure_default;
1197 uint64_t LowerOffset = RO.getOffset();
1198 uint64_t UpperOffset = LowerOffset + *NumElements * ElemSize;
1199 bool UpperOverflow = UpperOffset < LowerOffset;
1204 goto conjure_default;
1208 goto conjure_default;
1210 for (ClusterBindings::iterator I =
C->begin(), E =
C->end(); I != E;
1212 const BindingKey &BK = I.getKey();
1219 ((*ROffset >= LowerOffset && *ROffset < UpperOffset) ||
1221 (*ROffset >= LowerOffset || *ROffset < UpperOffset)) ||
1222 (LowerOffset == UpperOffset && *ROffset == LowerOffset))) {
1223 B = B.removeBinding(I.getKey());
1226 SVal
V = I.getData();
1227 const MemRegion *R =
V.getAsRegion();
1228 if (R && isa<SymbolicRegion>(R))
1235 DefinedOrUnknownSVal
V =
1236 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
1237 AT->getElementType(), Count);
1242 DefinedOrUnknownSVal
V = svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
1245 B = B.addBinding(baseR, BindingKey::Direct,
V);
1248 bool InvalidateRegionsWorker::isInitiallyIncludedGlobalRegion(
1249 const MemRegion *R) {
1250 switch (GlobalsFilter) {
1253 case GFK_SystemOnly:
1254 return isa<GlobalSystemSpaceRegion>(R->getMemorySpace());
1256 return isa<NonStaticGlobalSpaceRegion>(R->getMemorySpace());
1259 llvm_unreachable(
"unknown globals filter");
1262 bool InvalidateRegionsWorker::includeEntireMemorySpace(
const MemRegion *
Base) {
1263 if (isInitiallyIncludedGlobalRegion(
Base))
1266 const MemSpaceRegion *MemSpace =
Base->getMemorySpace();
1267 return ITraits.hasTrait(MemSpace,
1276 RegionBindingsRef B,
1277 InvalidatedRegions *Invalidated) {
1280 const GlobalsSpaceRegion *GS = MRMgr.getGlobalsRegion(K);
1281 SVal
V = svalBuilder.conjureSymbolVal( (
const void*) GS, Ex, LCtx,
1285 B = B.removeBinding(GS)
1291 Invalidated->push_back(GS);
1296 void RegionStoreManager::populateWorkList(InvalidateRegionsWorker &W,
1298 InvalidatedRegions *TopLevelRegions) {
1300 E = Values.end(); I != E; ++I) {
1303 V.getAs<nonloc::LazyCompoundVal>()) {
1305 const SValListTy &Vals = getInterestingValues(*LCS);
1307 for (SValListTy::const_iterator I = Vals.begin(),
1308 E = Vals.end(); I != E; ++I) {
1311 if (
const MemRegion *R = (*I).getAsRegion())
1317 if (
const MemRegion *R =
V.getAsRegion()) {
1318 if (TopLevelRegions)
1319 TopLevelRegions->push_back(R);
1327 RegionStoreManager::invalidateRegions(
Store store,
1329 const Expr *Ex,
unsigned Count,
1331 const CallEvent *Call,
1333 RegionAndSymbolInvalidationTraits &ITraits,
1334 InvalidatedRegions *TopLevelRegions,
1335 InvalidatedRegions *Invalidated) {
1338 if (
Call->isInSystemHeader())
1339 GlobalsFilter = GFK_SystemOnly;
1341 GlobalsFilter = GFK_All;
1343 GlobalsFilter = GFK_None;
1346 RegionBindingsRef B = getRegionBindings(store);
1347 InvalidateRegionsWorker W(*
this, StateMgr, B, Ex, Count, LCtx, IS, ITraits,
1348 Invalidated, GlobalsFilter);
1351 W.GenerateClusters();
1354 populateWorkList(W, Values, TopLevelRegions);
1359 B = W.getRegionBindings();
1365 switch (GlobalsFilter) {
1367 B = invalidateGlobalRegion(MemRegion::GlobalInternalSpaceRegionKind,
1368 Ex, Count, LCtx, B, Invalidated);
1370 case GFK_SystemOnly:
1371 B = invalidateGlobalRegion(MemRegion::GlobalSystemSpaceRegionKind,
1372 Ex, Count, LCtx, B, Invalidated);
1378 return StoreRef(B.asStore(), *
this);
1391 SVal RegionStoreManager::ArrayToPointer(Loc Array,
QualType T) {
1392 if (Array.getAs<loc::ConcreteInt>())
1395 if (!Array.getAs<loc::MemRegionVal>())
1396 return UnknownVal();
1398 const SubRegion *R =
1399 cast<SubRegion>(Array.castAs<loc::MemRegionVal>().getRegion());
1400 NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex();
1401 return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, R, Ctx));
1409 assert(!L.getAs<UnknownVal>() &&
"location unknown");
1410 assert(!L.getAs<UndefinedVal>() &&
"location undefined");
1418 if (L.getAs<loc::ConcreteInt>()) {
1419 return UnknownVal();
1421 if (!L.getAs<loc::MemRegionVal>()) {
1422 return UnknownVal();
1425 const MemRegion *MR = L.castAs<loc::MemRegionVal>().getRegion();
1427 if (isa<BlockDataRegion>(MR)) {
1428 return UnknownVal();
1431 if (!isa<TypedValueRegion>(MR)) {
1433 if (
const TypedRegion *TR = dyn_cast<TypedRegion>(MR))
1434 T = TR->getLocationType()->getPointeeType();
1435 else if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
1438 assert(!T.
isNull() &&
"Unable to auto-detect binding type!");
1439 assert(!T->
isVoidType() &&
"Attempting to dereference a void pointer!");
1440 MR = GetElementZeroRegion(cast<SubRegion>(MR), T);
1442 T = cast<TypedValueRegion>(MR)->getValueType();
1447 const TypedValueRegion *R = cast<TypedValueRegion>(MR);
1453 return UnknownVal();
1464 return getBindingForStruct(B, R);
1468 return createLazyBinding(B, R);
1472 return getBindingForArray(B, R);
1474 return UnknownVal();
1479 return UnknownVal();
1481 if (
const FieldRegion* FR = dyn_cast<FieldRegion>(R))
1482 return CastRetrievedVal(getBindingForField(B, FR), FR, T);
1484 if (
const ElementRegion* ER = dyn_cast<ElementRegion>(R)) {
1490 return CastRetrievedVal(getBindingForElement(B, ER), ER, T);
1493 if (
const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) {
1500 return CastRetrievedVal(getBindingForObjCIvar(B, IVR), IVR, T);
1503 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
1510 return CastRetrievedVal(getBindingForVar(B, VR), VR, T);
1513 const SVal *
V = B.lookup(R, BindingKey::Direct);
1522 if (R->hasStackNonParametersStorage()) {
1527 return UndefinedVal();
1531 return svalBuilder.getRegionValueSymbolVal(R);
1536 if (
const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R))
1537 RegionTy = TVR->getValueType();
1539 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
1540 RegionTy = SR->getSymbol()->getType();
1554 const SubRegion *R,
bool AllowSubregionBindings) {
1566 if (!RegionTy.
isNull() &&
1568 QualType SourceRegionTy = LCV->getRegion()->getValueType();
1569 if (!SVB.getContext().hasSameUnqualifiedType(RegionTy, SourceRegionTy))
1573 if (!AllowSubregionBindings) {
1579 if (Bindings.size() > 1)
1587 std::pair<Store, const SubRegion *>
1590 const SubRegion *originalRegion) {
1591 if (originalRegion != R) {
1594 return std::make_pair(
V->getStore(),
V->getRegion());
1597 typedef std::pair<Store, const SubRegion *> StoreRegionPair;
1598 StoreRegionPair Result = StoreRegionPair();
1600 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
1601 Result = findLazyBinding(B, cast<SubRegion>(ER->getSuperRegion()),
1605 Result.second = MRMgr.getElementRegionWithSuper(ER, Result.second);
1607 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
1608 Result = findLazyBinding(B, cast<SubRegion>(FR->getSuperRegion()),
1612 Result.second = MRMgr.getFieldRegionWithSuper(FR, Result.second);
1614 }
else if (
const CXXBaseObjectRegion *BaseReg =
1615 dyn_cast<CXXBaseObjectRegion>(R)) {
1618 Result = findLazyBinding(B, cast<SubRegion>(BaseReg->getSuperRegion()),
1622 Result.second = MRMgr.getCXXBaseObjectRegionWithSuper(BaseReg,
1630 const ElementRegion* R) {
1635 const MemRegion* superR = R->getSuperRegion();
1638 if (
const StringRegion *StrR = dyn_cast<StringRegion>(superR)) {
1643 return UnknownVal();
1646 SVal Idx = R->getIndex();
1648 int64_t i = CI->getValue().getSExtValue();
1652 return UndefinedVal();
1659 return svalBuilder.makeIntVal(
c, T);
1661 }
else if (
const VarRegion *VR = dyn_cast<VarRegion>(superR)) {
1664 const VarDecl *VD = VR->getDecl();
1666 R->getElementType().isConstQualified() ||
1669 if (
const auto *InitList = dyn_cast<InitListExpr>(Init)) {
1671 if (
auto CI = R->getIndex().getAs<nonloc::ConcreteInt>()) {
1672 int64_t i = CI->getValue().getSExtValue();
1676 return UndefinedVal();
1679 if (CAT->getSize().sle(i))
1680 return UndefinedVal();
1683 if (i >= InitList->getNumInits())
1684 return svalBuilder.makeZeroVal(R->getElementType());
1686 if (
const Expr *ElemInit = InitList->getInit(i))
1696 if (isa<CodeTextRegion>(superR))
1697 return UnknownVal();
1705 const RegionRawOffset &O = R->getAsArrayOffset();
1709 return UnknownVal();
1711 if (
const TypedValueRegion *baseR =
1712 dyn_cast_or_null<TypedValueRegion>(O.getRegion())) {
1713 QualType baseT = baseR->getValueType();
1715 QualType elemT = R->getElementType();
1720 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1722 if (
V->isUnknownOrUndef())
1726 return UnknownVal();
1732 return getBindingForFieldOrElementCommon(B, R, R->getElementType());
1736 const FieldRegion* R) {
1751 const MemRegion* superR = R->getSuperRegion();
1752 if (
const auto *VR = dyn_cast<VarRegion>(superR)) {
1753 const VarDecl *VD = VR->getDecl();
1762 if (
const auto *InitList = dyn_cast<InitListExpr>(Init)) {
1763 if (Index < InitList->getNumInits()) {
1764 if (
const Expr *FieldInit = InitList->getInit(Index))
1768 return svalBuilder.makeZeroVal(Ty);
1773 return getBindingForFieldOrElementCommon(B, R, Ty);
1778 const MemRegion *superR,
1779 const TypedValueRegion *R,
1783 const SVal &val = D.getValue();
1784 if (
SymbolRef parentSym = val.getAsSymbol())
1785 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1787 if (val.isZeroConstant())
1788 return svalBuilder.makeZeroVal(Ty);
1790 if (val.isUnknownOrUndef())
1795 if (val.getAs<nonloc::LazyCompoundVal>() ||
1796 val.getAs<nonloc::CompoundVal>())
1799 llvm_unreachable(
"Unknown default value");
1805 SVal RegionStoreManager::getLazyBinding(
const SubRegion *LazyBindingRegion,
1806 RegionBindingsRef LazyBinding) {
1808 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(LazyBindingRegion))
1809 Result = getBindingForElement(LazyBinding, ER);
1811 Result = getBindingForField(LazyBinding,
1812 cast<FieldRegion>(LazyBindingRegion));
1828 if (Result.isUndef())
1829 Result = UnknownVal();
1836 const TypedValueRegion *R,
1843 Store lazyBindingStore =
nullptr;
1844 const SubRegion *lazyBindingRegion =
nullptr;
1845 std::tie(lazyBindingStore, lazyBindingRegion) = findLazyBinding(B, R, R);
1846 if (lazyBindingRegion)
1847 return getLazyBinding(lazyBindingRegion,
1848 getRegionBindings(lazyBindingStore));
1852 bool hasSymbolicIndex =
false;
1868 bool hasPartialLazyBinding =
false;
1870 const SubRegion *SR = R;
1872 const MemRegion *
Base = SR->getSuperRegion();
1874 if (D->getAs<nonloc::LazyCompoundVal>()) {
1875 hasPartialLazyBinding =
true;
1882 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(
Base)) {
1883 NonLoc index = ER->getIndex();
1884 if (!index.isConstant())
1885 hasSymbolicIndex =
true;
1890 SR = dyn_cast<SubRegion>(
Base);
1893 if (R->hasStackNonParametersStorage()) {
1894 if (isa<ElementRegion>(R)) {
1897 if (
const TypedValueRegion *typedSuperR =
1898 dyn_cast<TypedValueRegion>(R->getSuperRegion())) {
1899 if (typedSuperR->getValueType()->isVectorType())
1900 return UnknownVal();
1908 if (hasSymbolicIndex)
1909 return UnknownVal();
1912 if (!hasPartialLazyBinding && !isa<BlockDataRegion>(R->getBaseRegion()))
1913 return UndefinedVal();
1917 return svalBuilder.getRegionValueSymbolVal(R);
1921 const ObjCIvarRegion* R) {
1926 const MemRegion *superR = R->getSuperRegion();
1931 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1934 return UnknownVal();
1937 return getBindingForLazySymbol(R);
1941 const VarRegion *R) {
1951 const VarDecl *VD = R->getDecl();
1952 const MemSpaceRegion *MS = R->getMemorySpace();
1955 if (isa<StackArgumentsSpaceRegion>(MS))
1956 return svalBuilder.getRegionValueSymbolVal(R);
1967 return UnknownVal();
1973 if (isa<UnknownSpaceRegion>(MS))
1974 return svalBuilder.getRegionValueSymbolVal(R);
1976 if (isa<GlobalsSpaceRegion>(MS)) {
1980 if (B.isMainAnalysis())
1989 if (isa<StaticGlobalSpaceRegion>(MS))
1990 return svalBuilder.makeZeroVal(T);
1992 if (
Optional<SVal> V = getBindingForDerivedDefaultValue(B, MS, R, T)) {
1993 assert(!
V->getAs<nonloc::LazyCompoundVal>());
1994 return V.getValue();
1997 return svalBuilder.getRegionValueSymbolVal(R);
2000 return UndefinedVal();
2003 SVal RegionStoreManager::getBindingForLazySymbol(
const TypedValueRegion *R) {
2005 return svalBuilder.getRegionValueSymbolVal(R);
2008 const RegionStoreManager::SValListTy &
2009 RegionStoreManager::getInterestingValues(nonloc::LazyCompoundVal LCV) {
2011 LazyBindingsMapTy::iterator I = LazyBindingsMap.find(LCV.getCVData());
2012 if (I != LazyBindingsMap.end())
2018 const SubRegion *LazyR = LCV.getRegion();
2019 RegionBindingsRef B = getRegionBindings(LCV.getStore());
2025 return (LazyBindingsMap[LCV.getCVData()] = std::move(List));
2034 if (
V.isUnknownOrUndef() ||
V.isConstant())
2038 V.getAs<nonloc::LazyCompoundVal>()) {
2039 const SValListTy &InnerList = getInterestingValues(*InnerLCV);
2040 List.insert(List.end(), InnerList.begin(), InnerList.end());
2047 return (LazyBindingsMap[LCV.getCVData()] = std::move(List));
2051 const TypedValueRegion *R) {
2056 return svalBuilder.makeLazyCompoundVal(StoreRef(B.asStore(), *
this), R);
2063 return CRD->getNumBases() == 0;
2068 const TypedValueRegion *R) {
2071 return UnknownVal();
2073 return createLazyBinding(B, R);
2077 const TypedValueRegion *R) {
2079 "Only constant array types can have compound bindings.");
2081 return createLazyBinding(B, R);
2084 bool RegionStoreManager::includedInBindings(
Store store,
2085 const MemRegion *region)
const {
2086 RegionBindingsRef B = getRegionBindings(store);
2087 region = region->getBaseRegion();
2090 if (B.lookup(region))
2094 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI) {
2096 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
2098 const SVal &D = CI.getData();
2099 if (
const MemRegion *R = D.getAsRegion())
2100 if (R->getBaseRegion() == region)
2112 StoreRef RegionStoreManager::killBinding(
Store ST, Loc L) {
2114 if (
const MemRegion* R = LV->getRegion())
2115 return StoreRef(getRegionBindings(ST).removeBinding(R)
2117 .getRootWithoutRetain(),
2120 return StoreRef(ST, *
this);
2125 if (L.getAs<loc::ConcreteInt>())
2129 const MemRegion *R = L.castAs<loc::MemRegionVal>().getRegion();
2132 if (
const TypedValueRegion* TR = dyn_cast<TypedValueRegion>(R)) {
2135 return bindArray(B, TR,
V);
2137 return bindStruct(B, TR,
V);
2139 return bindVector(B, TR,
V);
2141 return bindAggregate(B, TR,
V);
2144 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
2147 QualType T = SR->getSymbol()->getType();
2151 R = GetElementZeroRegion(SR, T);
2154 assert((!isa<CXXThisRegion>(R) || !B.lookup(R)) &&
2155 "'this' pointer is not an l-value and is not assignable");
2158 RegionBindingsRef NewB = removeSubRegionBindings(B, cast<SubRegion>(R));
2169 V = svalBuilder.makeNull();
2171 V = svalBuilder.makeZeroVal(T);
2175 V = svalBuilder.makeZeroVal(Ctx.
IntTy);
2191 const TypedValueRegion* R,
2199 Size = CAT->getSize().getZExtValue();
2205 SVal
V = getBinding(B.asStore(), *MRV, R->getValueType());
2206 return bindAggregate(B, R,
V);
2210 if (Init.getAs<nonloc::LazyCompoundVal>())
2211 return bindAggregate(B, R, Init);
2213 if (Init.isUnknown())
2214 return bindAggregate(B, R, UnknownVal());
2217 const nonloc::CompoundVal& CV = Init.castAs<nonloc::CompoundVal>();
2221 RegionBindingsRef NewB(B);
2223 for (;
Size.hasValue() ? i <
Size.getValue() :
true ; ++i, ++VI) {
2228 const NonLoc &Idx = svalBuilder.makeArrayIndex(i);
2229 const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx);
2232 NewB = bindStruct(NewB, ER, *VI);
2234 NewB = bindArray(NewB, ER, *VI);
2236 NewB = bind(NewB, loc::MemRegionVal(ER), *VI);
2242 if (!
Size.hasValue() || i <
Size.getValue())
2243 NewB = setImplicitDefaultValue(NewB, R, ElementTy);
2249 const TypedValueRegion* R,
2255 if (
V.getAs<nonloc::LazyCompoundVal>() ||
V.getAs<nonloc::SymbolVal>())
2256 return bindAggregate(B, R,
V);
2261 if (!
V.getAs<nonloc::CompoundVal>()) {
2262 return bindAggregate(B, R, UnknownVal());
2266 nonloc::CompoundVal CV =
V.castAs<nonloc::CompoundVal>();
2269 RegionBindingsRef NewB(B);
2271 for ( ; index != numElements ; ++index) {
2275 NonLoc Idx = svalBuilder.makeArrayIndex(index);
2276 const ElementRegion *ER = MRMgr.getElementRegion(ElemType, Idx, R, Ctx);
2279 NewB = bindArray(NewB, ER, *VI);
2281 NewB = bindStruct(NewB, ER, *VI);
2283 NewB = bind(NewB, loc::MemRegionVal(ER), *VI);
2290 const TypedValueRegion *R,
2292 nonloc::LazyCompoundVal LCV) {
2295 if (
const CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(RD))
2296 if (
Class->getNumBases() != 0 ||
Class->getNumVBases() != 0)
2299 for (
const auto *FD : RD->
fields()) {
2305 if (Fields.size() == SmallStructLimit)
2312 Fields.push_back(FD);
2315 RegionBindingsRef NewB = B;
2317 for (FieldVector::iterator I = Fields.begin(), E = Fields.end(); I != E; ++I){
2318 const FieldRegion *SourceFR = MRMgr.getFieldRegion(*I, LCV.getRegion());
2319 SVal
V = getBindingForField(getRegionBindings(LCV.getStore()), SourceFR);
2321 const FieldRegion *DestFR = MRMgr.getFieldRegion(*I, R);
2322 NewB = bind(NewB, loc::MemRegionVal(DestFR),
V);
2329 const TypedValueRegion* R,
2331 if (!Features.supportsFields())
2340 if (!RD->isCompleteDefinition())
2345 V.getAs<nonloc::LazyCompoundVal>()) {
2348 return bindAggregate(B, R,
V);
2350 if (
V.getAs<nonloc::SymbolVal>())
2351 return bindAggregate(B, R,
V);
2356 if (
V.isUnknown() || !
V.getAs<nonloc::CompoundVal>())
2357 return bindAggregate(B, R, UnknownVal());
2375 const nonloc::CompoundVal& CV =
V.castAs<nonloc::CompoundVal>();
2378 RegionBindingsRef NewB(B);
2382 if (
const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
2390 assert((CRD->isAggregate() || (Ctx.
getLangOpts().ObjC && VI == VE)) &&
2391 "Non-aggregates are constructed with a constructor!");
2393 for (
const auto &B : CRD->bases()) {
2395 assert(!B.isVirtual() &&
"Aggregates cannot have virtual base classes!");
2404 assert(BRD &&
"Base classes must be C++ classes!");
2406 const CXXBaseObjectRegion *BR =
2407 MRMgr.getCXXBaseObjectRegion(BRD, R,
false);
2409 NewB = bindStruct(NewB, BR, *VI);
2417 for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI) {
2423 if (FI->isUnnamedBitfield())
2427 const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
2430 NewB = bindArray(NewB, FR, *VI);
2432 NewB = bindStruct(NewB, FR, *VI);
2434 NewB = bind(NewB, loc::MemRegionVal(FR), *VI);
2441 svalBuilder.makeIntVal(0,
false));
2449 const TypedRegion *R,
2461 class RemoveDeadBindingsWorker
2462 :
public ClusterAnalysis<RemoveDeadBindingsWorker> {
2464 SymbolReaper &SymReaper;
2468 RemoveDeadBindingsWorker(RegionStoreManager &rm,
2469 ProgramStateManager &stateMgr,
2470 RegionBindingsRef
b, SymbolReaper &symReaper,
2472 : ClusterAnalysis<RemoveDeadBindingsWorker>(rm, stateMgr,
b),
2473 SymReaper(symReaper), CurrentLCtx(LCtx) {}
2476 void VisitAddedToCluster(
const MemRegion *baseR,
const ClusterBindings &C);
2478 using ClusterAnalysis<RemoveDeadBindingsWorker>::VisitCluster;
2480 using ClusterAnalysis::AddToWorkList;
2482 bool AddToWorkList(
const MemRegion *R);
2484 bool UpdatePostponed();
2485 void VisitBinding(SVal
V);
2489 bool RemoveDeadBindingsWorker::AddToWorkList(
const MemRegion *R) {
2490 const MemRegion *BaseR = R->getBaseRegion();
2491 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
2494 void RemoveDeadBindingsWorker::VisitAddedToCluster(
const MemRegion *baseR,
2497 if (
const VarRegion *VR = dyn_cast<VarRegion>(baseR)) {
2498 if (SymReaper.isLive(VR))
2499 AddToWorkList(baseR, &C);
2504 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
2505 if (SymReaper.isLive(SR->getSymbol()))
2506 AddToWorkList(SR, &C);
2508 Postponed.push_back(SR);
2513 if (isa<NonStaticGlobalSpaceRegion>(baseR)) {
2514 AddToWorkList(baseR, &C);
2519 if (
const CXXThisRegion *TR = dyn_cast<CXXThisRegion>(baseR)) {
2520 const auto *StackReg =
2521 cast<StackArgumentsSpaceRegion>(TR->getSuperRegion());
2524 (RegCtx == CurrentLCtx || RegCtx->isParentOf(CurrentLCtx)))
2525 AddToWorkList(TR, &C);
2529 void RemoveDeadBindingsWorker::VisitCluster(
const MemRegion *baseR,
2536 if (
const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(baseR))
2537 SymReaper.markLive(SymR->getSymbol());
2539 for (ClusterBindings::iterator I =
C->begin(), E =
C->end(); I != E; ++I) {
2541 SymReaper.markElementIndicesLive(I.getKey().getRegion());
2543 VisitBinding(I.getData());
2547 void RemoveDeadBindingsWorker::VisitBinding(SVal
V) {
2550 V.getAs<nonloc::LazyCompoundVal>()) {
2552 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
2554 for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
2563 if (
const MemRegion *R =
V.getAsRegion()) {
2565 SymReaper.markLive(R);
2568 if (
const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(R)) {
2569 BlockDataRegion::referenced_vars_iterator I = BR->referenced_vars_begin(),
2570 E = BR->referenced_vars_end();
2571 for ( ; I != E; ++I)
2572 AddToWorkList(I.getCapturedRegion());
2578 for (
auto SI =
V.symbol_begin(), SE =
V.symbol_end(); SI!=SE; ++SI)
2579 SymReaper.markLive(*SI);
2582 bool RemoveDeadBindingsWorker::UpdatePostponed() {
2585 bool Changed =
false;
2587 for (
auto I = Postponed.begin(), E = Postponed.end(); I != E; ++I) {
2588 if (
const SymbolicRegion *SR = *I) {
2589 if (SymReaper.isLive(SR->getSymbol())) {
2590 Changed |= AddToWorkList(SR);
2599 StoreRef RegionStoreManager::removeDeadBindings(
Store store,
2601 SymbolReaper& SymReaper) {
2602 RegionBindingsRef B = getRegionBindings(store);
2603 RemoveDeadBindingsWorker W(*
this, StateMgr, B, SymReaper, LCtx);
2604 W.GenerateClusters();
2608 E = SymReaper.region_end(); I != E; ++I) {
2609 W.AddToWorkList(*I);
2612 do W.RunWorkList();
while (W.UpdatePostponed());
2617 for (RegionBindingsRef::iterator I = B.begin(), E = B.end(); I != E; ++I) {
2618 const MemRegion *
Base = I.getKey();
2622 if (!W.isVisited(
Base))
2626 return StoreRef(B.asStore(), *
this);
2633 void RegionStoreManager::printJson(raw_ostream &Out,
Store S,
const char *NL,
2634 unsigned int Space,
bool IsDot)
const {
2635 RegionBindingsRef Bindings = getRegionBindings(S);
2637 Indent(Out, Space, IsDot) <<
"\"store\": ";
2639 if (Bindings.isEmpty()) {
2640 Out <<
"null," << NL;
2644 Out <<
"{ \"pointer\": \"" << Bindings.asStore() <<
"\", \"items\": [" << NL;
2645 Bindings.printJson(Out, NL, Space + 1, IsDot);
2646 Indent(Out, Space, IsDot) <<
"]}," << NL;
A (possibly-)qualified type.
static void getSymbolicOffsetFields(BindingKey K, FieldVector &Fields)
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
llvm::DenseSet< SymbolRef > InvalidatedSymbols
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion.
internal::Matcher< Stmt > StatementMatcher
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isRecordType() const
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 internal::ArgumentAdaptingMatcherFunc< internal::HasDescendantMatcher > hasDescendant
Matches AST nodes that have descendant AST nodes that match the provided matcher.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
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.
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
QualType getElementType() const
Represents a variable declaration or definition.
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
std::unique_ptr< StoreManager > CreateFieldsOnlyRegionStoreManager(ProgramStateManager &StMgr)
Represents a struct/union/class.
llvm::ImmutableMap< BindingKey, SVal > ClusterBindings
SmallVector< const FieldDecl *, 8 > FieldVector
const SymExpr * SymbolRef
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
Represents a member of a struct/union/class.
static bool canSymbolicate(QualType T)
bool isReferenceType() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
static bool isLocType(QualType T)
unsigned getLength() const
const internal::VariadicDynCastAllOfMatcher< Stmt, DeclRefExpr > declRefExpr
Matches expressions that refer to declarations.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
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
SmallVector< const MemRegion *, 8 > InvalidatedRegions
bool isScalarType() const
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
std::unique_ptr< StoreManager > CreateRegionStoreManager(ProgramStateManager &StMgr)
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
static bool isCompatibleWithFields(BindingKey K, const FieldVector &Fields)
When applied to a MemSpaceRegion, indicates the entire memory space should be invalidated.
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.
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>.
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
uint32_t getCodeUnit(size_t i) const
bool isAnyComplexType() const
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.
llvm::ImmutableMapRef< BindingKey, SVal > ClusterBindingsRef
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isVoidPointerType() const
Maps string IDs to AST nodes matched by parts of a matcher.
bool isStructureOrClassType() const
bool isUnnamedBitfield() const
Determines whether this is an unnamed bitfield.
QualType getElementType() 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.
const ConstantArrayType * getAsConstantArrayType(QualType T) const
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
bool isAnyPointerType() const
constexpr XRayInstrMask None
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
bool isVectorType() const
Tells that a region's contents is not changed.
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.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
const Decl * getDecl() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
const StackFrameContext * getStackFrame() const
std::pair< BindingKey, SVal > BindingPair
bool isConstantArrayType() const
Stores options for the analyzer from the command line.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
It represents a stack frame of the call stack (based on CallEvent).
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
__PTRDIFF_TYPE__ ptrdiff_t
A signed integer type that is the result of subtracting two pointers.
static bool isUnionField(const FieldRegion *FR)
Represents a C++ struct/union/class.
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
unsigned getNumElements() const
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const RegionBindingsRef & RegionBindingsConstRef
const LangOptions & getLangOpts() const
Represents the canonical version of C arrays with a specified constant size.
__device__ __2f16 float c