30 #include "llvm/ADT/ImmutableMap.h" 31 #include "llvm/ADT/Optional.h" 32 #include "llvm/Support/raw_ostream.h" 35 using namespace clang;
47 enum { Symbolic = 0x2 };
49 llvm::PointerIntPair<const MemRegion *, 2>
P;
54 explicit BindingKey(
const SubRegion *
r,
const SubRegion *
Base,
Kind k)
55 : P(r, k | Symbolic), Data(reinterpret_cast<
uintptr_t>(Base)) {
56 assert(r && Base &&
"Must have known regions.");
57 assert(getConcreteOffsetRegion() == Base &&
"Failed to store base region");
61 explicit BindingKey(
const MemRegion *r, uint64_t offset,
Kind k)
62 : P(r, k), Data(offset) {
63 assert(r &&
"Must have known regions.");
64 assert(getOffset() == offset &&
"Failed to store offset");
65 assert((r == r->getBaseRegion() || isa<ObjCIvarRegion>(
r) ||
66 isa <CXXDerivedObjectRegion>(r)) &&
71 bool isDirect()
const {
return P.getInt() & Direct; }
72 bool hasSymbolicOffset()
const {
return P.getInt() & Symbolic; }
74 const MemRegion *getRegion()
const {
return P.getPointer(); }
75 uint64_t getOffset()
const {
76 assert(!hasSymbolicOffset());
80 const SubRegion *getConcreteOffsetRegion()
const {
81 assert(hasSymbolicOffset());
82 return reinterpret_cast<const SubRegion *
>(
static_cast<uintptr_t>(Data));
85 const MemRegion *getBaseRegion()
const {
86 if (hasSymbolicOffset())
87 return getConcreteOffsetRegion()->getBaseRegion();
88 return getRegion()->getBaseRegion();
91 void Profile(llvm::FoldingSetNodeID&
ID)
const {
92 ID.AddPointer(P.getOpaqueValue());
96 static BindingKey
Make(
const MemRegion *R,
Kind k);
99 if (P.getOpaqueValue() < X.P.getOpaqueValue())
101 if (P.getOpaqueValue() > X.P.getOpaqueValue())
103 return Data < X.Data;
107 return P.getOpaqueValue() == X.P.getOpaqueValue() &&
116 const RegionOffset &RO = R->getAsOffset();
117 if (RO.hasSymbolicOffset())
118 return BindingKey(cast<SubRegion>(R), cast<SubRegion>(RO.getRegion()), k);
120 return BindingKey(RO.getRegion(), RO.getOffset(), k);
124 static inline raw_ostream &
operator<<(raw_ostream &Out, BindingKey K) {
125 Out <<
"\"kind\": \"" << (K.isDirect() ?
"Direct" :
"Default")
126 <<
"\", \"offset\": ";
128 if (!K.hasSymbolicOffset())
129 Out << K.getOffset();
148 typedef llvm::ImmutableMap<const MemRegion *, ClusterBindings>
152 class RegionBindingsRef :
public llvm::ImmutableMapRef<const MemRegion *,
154 ClusterBindings::Factory *CBFactory;
157 typedef llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>
160 RegionBindingsRef(ClusterBindings::Factory &CBFactory,
161 const RegionBindings::TreeTy *T,
162 RegionBindings::TreeTy::Factory *F)
163 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(T, F),
164 CBFactory(&CBFactory) {}
166 RegionBindingsRef(
const ParentTy &P, ClusterBindings::Factory &CBFactory)
167 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(
P),
168 CBFactory(&CBFactory) {}
170 RegionBindingsRef add(key_type_ref K, data_type_ref D)
const {
171 return RegionBindingsRef(static_cast<const ParentTy *>(
this)->add(K, D),
175 RegionBindingsRef
remove(key_type_ref K)
const {
176 return RegionBindingsRef(static_cast<const ParentTy *>(
this)->
remove(K),
180 RegionBindingsRef addBinding(BindingKey K, SVal
V)
const;
182 RegionBindingsRef addBinding(
const MemRegion *R,
183 BindingKey::Kind k, SVal V)
const;
185 const SVal *lookup(BindingKey K)
const;
186 const SVal *lookup(
const MemRegion *R, BindingKey::Kind k)
const;
187 using llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>::lookup;
189 RegionBindingsRef removeBinding(BindingKey K);
191 RegionBindingsRef removeBinding(
const MemRegion *R,
194 RegionBindingsRef removeBinding(
const MemRegion *R) {
195 return removeBinding(R, BindingKey::Direct).
206 Store asStore()
const {
207 return asImmutableMap().getRootWithoutRetain();
210 void printJson(raw_ostream &Out,
const char *NL =
"\n",
211 unsigned int Space = 0,
bool IsDot =
false)
const {
212 for (iterator I = begin(); I != end(); ++I) {
215 <<
"{ \"cluster\": \"" << I.getKey() <<
"\", \"pointer\": \"" 216 << (
const void *)I.getKey() <<
"\", \"items\": [" << NL;
219 const ClusterBindings &CB = I.getData();
220 for (ClusterBindings::iterator CI = CB.begin(); CI != CB.end(); ++CI) {
221 Indent(Out, Space, IsDot) <<
"{ " << CI.getKey() <<
", \"value\": ";
222 CI.getData().printJson(Out,
true);
224 if (std::next(CI) != CB.end())
230 Indent(Out, Space, IsDot) <<
"]}";
231 if (std::next(I) != end())
237 LLVM_DUMP_METHOD
void dump()
const { printJson(llvm::errs()); }
243 Optional<SVal> RegionBindingsRef::getDirectBinding(
const MemRegion *R)
const {
247 Optional<SVal> RegionBindingsRef::getDefaultBinding(
const MemRegion *R)
const {
251 RegionBindingsRef RegionBindingsRef::addBinding(BindingKey K, SVal
V)
const {
252 const MemRegion *Base = K.getBaseRegion();
254 const ClusterBindings *ExistingCluster = lookup(Base);
255 ClusterBindings Cluster =
256 (ExistingCluster ? *ExistingCluster : CBFactory->getEmptyMap());
258 ClusterBindings NewCluster = CBFactory->add(Cluster, K, V);
259 return add(Base, NewCluster);
263 RegionBindingsRef RegionBindingsRef::addBinding(
const MemRegion *R,
269 const SVal *RegionBindingsRef::lookup(BindingKey K)
const {
270 const ClusterBindings *Cluster = lookup(K.getBaseRegion());
273 return Cluster->lookup(K);
276 const SVal *RegionBindingsRef::lookup(
const MemRegion *R,
277 BindingKey::Kind k)
const {
281 RegionBindingsRef RegionBindingsRef::removeBinding(BindingKey K) {
282 const MemRegion *Base = K.getBaseRegion();
283 const ClusterBindings *Cluster = lookup(Base);
287 ClusterBindings NewCluster = CBFactory->remove(*Cluster, K);
288 if (NewCluster.isEmpty())
290 return add(Base, NewCluster);
293 RegionBindingsRef RegionBindingsRef::removeBinding(
const MemRegion *R,
303 struct minimal_features_tag {};
304 struct maximal_features_tag {};
306 class RegionStoreFeatures {
309 RegionStoreFeatures(minimal_features_tag) :
310 SupportsFields(
false) {}
312 RegionStoreFeatures(maximal_features_tag) :
313 SupportsFields(
true) {}
315 void enableFields(
bool t) { SupportsFields =
t; }
317 bool supportsFields()
const {
return SupportsFields; }
326 class InvalidateRegionsWorker;
328 class RegionStoreManager :
public StoreManager {
330 const RegionStoreFeatures Features;
332 RegionBindings::Factory RBFactory;
333 mutable ClusterBindings::Factory CBFactory;
335 typedef std::vector<SVal> SValListTy;
337 typedef llvm::DenseMap<
const LazyCompoundValData *,
338 SValListTy> LazyBindingsMapTy;
339 LazyBindingsMapTy LazyBindingsMap;
349 unsigned SmallStructLimit;
353 void populateWorkList(InvalidateRegionsWorker &W,
355 InvalidatedRegions *TopLevelRegions);
358 RegionStoreManager(ProgramStateManager& mgr,
const RegionStoreFeatures &f)
359 : StoreManager(mgr), Features(f),
360 RBFactory(mgr.getAllocator()), CBFactory(mgr.getAllocator()),
361 SmallStructLimit(0) {
362 SubEngine &Eng = StateMgr.getOwningEngine();
364 SmallStructLimit = Options.RegionStoreSmallStructLimit;
371 RegionBindingsRef setImplicitDefaultValue(RegionBindingsConstRef B,
380 SVal ArrayToPointer(Loc Array,
QualType ElementTy)
override;
383 return StoreRef(RBFactory.getEmptyMap().getRootWithoutRetain(), *
this);
394 InvalidatedRegions *Invalidated);
396 StoreRef invalidateRegions(
Store store,
398 const Expr *E,
unsigned Count,
402 RegionAndSymbolInvalidationTraits &ITraits,
403 InvalidatedRegions *Invalidated,
404 InvalidatedRegions *InvalidatedTopLevel)
override;
406 bool scanReachableSymbols(
Store S,
const MemRegion *R,
407 ScanReachableSymbols &Callbacks)
override;
409 RegionBindingsRef removeSubRegionBindings(RegionBindingsConstRef B,
414 StoreRef Bind(
Store store, Loc LV, SVal V)
override {
415 return StoreRef(bind(getRegionBindings(store), LV, V).asStore(), *
this);
418 RegionBindingsRef bind(RegionBindingsConstRef B, Loc LV, SVal V);
422 StoreRef BindDefaultInitial(
Store store,
const MemRegion *R,
424 RegionBindingsRef B = getRegionBindings(store);
427 assert(!(B.getDefaultBinding(R) || B.getDirectBinding(R)) &&
428 "Double initialization!");
430 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *
this);
435 StoreRef BindDefaultZero(
Store store,
const MemRegion *R)
override {
445 if (
const auto *BR = dyn_cast<CXXBaseObjectRegion>(R))
446 if (BR->getDecl()->isEmpty())
447 return StoreRef(store, *
this);
449 RegionBindingsRef B = getRegionBindings(store);
450 SVal V = svalBuilder.makeZeroVal(Ctx.CharTy);
451 B = removeSubRegionBindings(B, cast<SubRegion>(R));
453 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *
this);
467 const TypedValueRegion *R,
469 nonloc::LazyCompoundVal LCV);
472 RegionBindingsRef bindStruct(RegionBindingsConstRef B,
473 const TypedValueRegion* R, SVal V);
476 RegionBindingsRef bindVector(RegionBindingsConstRef B,
477 const TypedValueRegion* R, SVal V);
479 RegionBindingsRef bindArray(RegionBindingsConstRef B,
480 const TypedValueRegion* R,
485 RegionBindingsRef bindAggregate(RegionBindingsConstRef B,
486 const TypedRegion *R,
492 StoreRef killBinding(
Store ST, Loc L)
override;
494 void incrementReferenceCount(
Store store)
override {
495 getRegionBindings(store).manualRetain();
501 void decrementReferenceCount(
Store store)
override {
502 getRegionBindings(store).manualRelease();
505 bool includedInBindings(
Store store,
const MemRegion *region)
const override;
521 return getBinding(getRegionBindings(S), L, T);
525 RegionBindingsRef B = getRegionBindings(S);
529 return B.getDefaultBinding(R->getBaseRegion());
534 SVal getBindingForElement(RegionBindingsConstRef B,
const ElementRegion *R);
536 SVal getBindingForField(RegionBindingsConstRef B,
const FieldRegion *R);
538 SVal getBindingForObjCIvar(RegionBindingsConstRef B,
const ObjCIvarRegion *R);
540 SVal getBindingForVar(RegionBindingsConstRef B,
const VarRegion *R);
542 SVal getBindingForLazySymbol(
const TypedValueRegion *R);
544 SVal getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
545 const TypedValueRegion *R,
548 SVal getLazyBinding(
const SubRegion *LazyBindingRegion,
549 RegionBindingsRef LazyBinding);
556 SVal getBindingForStruct(RegionBindingsConstRef B,
const TypedValueRegion *R);
557 SVal getBindingForArray(RegionBindingsConstRef B,
const TypedValueRegion *R);
558 NonLoc createLazyBinding(RegionBindingsConstRef B,
const TypedValueRegion *R);
565 Optional<SVal> getBindingForDerivedDefaultValue(RegionBindingsConstRef B,
566 const MemRegion *superR,
567 const TypedValueRegion *R,
574 std::pair<Store, const SubRegion *>
575 findLazyBinding(RegionBindingsConstRef B,
const SubRegion *R,
576 const SubRegion *originalRegion);
584 const SValListTy &getInterestingValues(nonloc::LazyCompoundVal LCV);
593 SymbolReaper& SymReaper)
override;
608 RegionBindingsRef getRegionBindings(
Store store)
const {
609 return RegionBindingsRef(CBFactory,
610 static_cast<const RegionBindings::TreeTy*>(store),
611 RBFactory.getTreeFactory());
614 void printJson(raw_ostream &Out,
Store S,
const char *NL =
"\n",
615 unsigned int Space = 0,
bool IsDot =
false)
const override;
617 void iterBindings(
Store store, BindingsHandler& f)
override {
618 RegionBindingsRef B = getRegionBindings(store);
619 for (RegionBindingsRef::iterator I = B.begin(), E = B.end(); I != E; ++I) {
620 const ClusterBindings &Cluster = I.getData();
621 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
623 const BindingKey &K = CI.getKey();
626 if (
const SubRegion *R = dyn_cast<SubRegion>(K.getRegion())) {
628 if (!f.HandleBinding(*
this, store, R, CI.getData()))
642 std::unique_ptr<StoreManager>
644 RegionStoreFeatures F = maximal_features_tag();
645 return llvm::make_unique<RegionStoreManager>(StMgr, F);
648 std::unique_ptr<StoreManager>
650 RegionStoreFeatures F = minimal_features_tag();
651 F.enableFields(
true);
652 return llvm::make_unique<RegionStoreManager>(StMgr, F);
672 template <
typename DERIVED>
673 class ClusterAnalysis {
675 typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
676 typedef const MemRegion * WorkListElement;
679 llvm::SmallPtrSet<const ClusterBindings *, 16> Visited;
683 RegionStoreManager &RM;
685 SValBuilder &svalBuilder;
691 const ClusterBindings *getCluster(
const MemRegion *R) {
698 bool includeEntireMemorySpace(
const MemRegion *Base) {
703 ClusterAnalysis(RegionStoreManager &rm, ProgramStateManager &StateMgr,
705 : RM(rm), Ctx(StateMgr.getContext()),
706 svalBuilder(StateMgr.getSValBuilder()), B(std::move(b)) {}
708 RegionBindingsRef getRegionBindings()
const {
return B; }
710 bool isVisited(
const MemRegion *R) {
711 return Visited.count(getCluster(R));
714 void GenerateClusters() {
716 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end();
718 const MemRegion *Base = RI.getKey();
720 const ClusterBindings &Cluster = RI.getData();
721 assert(!Cluster.isEmpty() &&
"Empty clusters should be removed");
722 static_cast<DERIVED*
>(
this)->VisitAddedToCluster(Base, Cluster);
726 if (static_cast<DERIVED*>(
this)->includeEntireMemorySpace(Base))
727 AddToWorkList(WorkListElement(Base), &Cluster);
731 bool AddToWorkList(WorkListElement E,
const ClusterBindings *C) {
732 if (C && !Visited.insert(C).second)
738 bool AddToWorkList(
const MemRegion *R) {
739 return static_cast<DERIVED*
>(
this)->AddToWorkList(R);
743 while (!WL.empty()) {
744 WorkListElement E = WL.pop_back_val();
745 const MemRegion *BaseR = E;
747 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, getCluster(BaseR));
751 void VisitAddedToCluster(
const MemRegion *baseR,
const ClusterBindings &C) {}
752 void VisitCluster(
const MemRegion *baseR,
const ClusterBindings *C) {}
754 void VisitCluster(
const MemRegion *BaseR,
const ClusterBindings *C,
756 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, C);
765 bool RegionStoreManager::scanReachableSymbols(
Store S,
const MemRegion *R,
766 ScanReachableSymbols &Callbacks) {
767 assert(R == R->getBaseRegion() &&
"Should only be called for base regions");
768 RegionBindingsRef B = getRegionBindings(S);
769 const ClusterBindings *Cluster = B.lookup(R);
774 for (ClusterBindings::iterator RI = Cluster->begin(), RE = Cluster->end();
776 if (!Callbacks.scan(RI.getData()))
784 return FR->getDecl()->getParent()->isUnion();
790 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
792 const MemRegion *Base = K.getConcreteOffsetRegion();
793 const MemRegion *R = K.getRegion();
796 if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R))
798 Fields.push_back(FR->getDecl());
800 R = cast<SubRegion>(R)->getSuperRegion();
805 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
810 FieldVector FieldsInBindingKey;
813 ptrdiff_t Delta = FieldsInBindingKey.size() - Fields.size();
815 return std::equal(FieldsInBindingKey.begin() + Delta,
816 FieldsInBindingKey.end(),
819 return std::equal(FieldsInBindingKey.begin(), FieldsInBindingKey.end(),
820 Fields.begin() - Delta);
834 SValBuilder &SVB,
const ClusterBindings &Cluster,
835 const SubRegion *Top, BindingKey TopKey,
836 bool IncludeAllDefaultBindings) {
837 FieldVector FieldsInSymbolicSubregions;
838 if (TopKey.hasSymbolicOffset()) {
840 Top = TopKey.getConcreteOffsetRegion();
845 uint64_t Length = UINT64_MAX;
846 SVal Extent = Top->getExtent(SVB);
848 Extent.getAs<nonloc::ConcreteInt>()) {
849 const llvm::APSInt &ExtentInt = ExtentCI->getValue();
850 assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned());
852 Length = ExtentInt.getLimitedValue() * SVB.getContext().getCharWidth();
853 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(Top)) {
854 if (FR->getDecl()->isBitField())
855 Length = FR->getDecl()->getBitWidthValue(SVB.getContext());
858 for (ClusterBindings::iterator I = Cluster.begin(), E = Cluster.end();
860 BindingKey NextKey = I.getKey();
861 if (NextKey.getRegion() == TopKey.getRegion()) {
867 if (NextKey.getOffset() > TopKey.getOffset() &&
868 NextKey.getOffset() - TopKey.getOffset() < Length) {
871 Bindings.push_back(*I);
873 }
else if (NextKey.getOffset() == TopKey.getOffset()) {
880 if (IncludeAllDefaultBindings || NextKey.isDirect())
881 Bindings.push_back(*I);
884 }
else if (NextKey.hasSymbolicOffset()) {
885 const MemRegion *Base = NextKey.getConcreteOffsetRegion();
886 if (Top->isSubRegionOf(Base) && Top != Base) {
890 if (IncludeAllDefaultBindings || NextKey.isDirect())
892 Bindings.push_back(*I);
893 }
else if (
const SubRegion *BaseSR = dyn_cast<SubRegion>(Base)) {
896 if (BaseSR->isSubRegionOf(Top))
898 Bindings.push_back(*I);
906 SValBuilder &SVB,
const ClusterBindings &Cluster,
907 const SubRegion *Top,
bool IncludeAllDefaultBindings) {
910 IncludeAllDefaultBindings);
914 RegionStoreManager::removeSubRegionBindings(RegionBindingsConstRef B,
915 const SubRegion *Top) {
917 const MemRegion *ClusterHead = TopKey.getBaseRegion();
919 if (Top == ClusterHead) {
921 return B.remove(Top);
924 const ClusterBindings *Cluster = B.lookup(ClusterHead);
928 if (TopKey.hasSymbolicOffset()) {
929 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
939 ClusterBindingsRef Result(*Cluster, CBFactory);
943 Result = Result.remove(I->first);
949 if (TopKey.hasSymbolicOffset()) {
950 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
955 if (Result.isEmpty())
956 return B.remove(ClusterHead);
957 return B.add(ClusterHead, Result.asImmutableMap());
961 class InvalidateRegionsWorker :
public ClusterAnalysis<InvalidateRegionsWorker>
967 RegionAndSymbolInvalidationTraits &ITraits;
971 InvalidateRegionsWorker(RegionStoreManager &rm,
972 ProgramStateManager &stateMgr,
974 const Expr *ex,
unsigned count,
977 RegionAndSymbolInvalidationTraits &ITraitsIn,
980 : ClusterAnalysis<InvalidateRegionsWorker>(rm, stateMgr,
b),
981 Ex(ex), Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r),
982 GlobalsFilter(GFK) {}
984 void VisitCluster(
const MemRegion *baseR,
const ClusterBindings *C);
985 void VisitBinding(SVal V);
987 using ClusterAnalysis::AddToWorkList;
989 bool AddToWorkList(
const MemRegion *R);
993 bool includeEntireMemorySpace(
const MemRegion *Base);
997 bool isInitiallyIncludedGlobalRegion(
const MemRegion *R);
1001 bool InvalidateRegionsWorker::AddToWorkList(
const MemRegion *R) {
1002 bool doNotInvalidateSuperRegion = ITraits.hasTrait(
1004 const MemRegion *BaseR = doNotInvalidateSuperRegion ? R : R->getBaseRegion();
1005 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
1008 void InvalidateRegionsWorker::VisitBinding(SVal V) {
1013 if (
const MemRegion *R = V.getAsRegion()) {
1020 V.getAs<nonloc::LazyCompoundVal>()) {
1022 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
1024 for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
1033 void InvalidateRegionsWorker::VisitCluster(
const MemRegion *baseR,
1034 const ClusterBindings *C) {
1036 bool PreserveRegionsContents =
1037 ITraits.hasTrait(baseR,
1041 for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E; ++I)
1042 VisitBinding(I.getData());
1045 if (!PreserveRegionsContents)
1046 B = B.remove(baseR);
1049 if (
const auto *TO = dyn_cast<TypedValueRegion>(baseR)) {
1050 if (
const auto *RD = TO->getValueType()->getAsCXXRecordDecl()) {
1055 if (RD->isLambda() && RD->getLambdaCallOperator()->getBody()) {
1058 const char *DeclBind =
"DeclBind";
1060 to(
varDecl(hasStaticStorageDuration()).bind(DeclBind)))));
1062 match(RefToStatic, *RD->getLambdaCallOperator()->getBody(),
1063 RD->getASTContext());
1066 auto *VD = Match.getNodeAs<
VarDecl>(DeclBind);
1067 const VarRegion *ToInvalidate =
1068 RM.getRegionManager().getVarRegion(VD, LCtx);
1069 AddToWorkList(ToInvalidate);
1077 if (
const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(baseR)) {
1078 for (BlockDataRegion::referenced_vars_iterator
1079 BI = BR->referenced_vars_begin(), BE = BR->referenced_vars_end() ;
1081 const VarRegion *VR = BI.getCapturedRegion();
1082 const VarDecl *VD = VR->getDecl();
1092 SVal V = RM.getBinding(B, loc::MemRegionVal(VR));
1094 if (
const MemRegion *LR = L->getAsRegion())
1103 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
1104 IS.insert(SR->getSymbol());
1107 if (PreserveRegionsContents)
1112 Regions->push_back(baseR);
1114 if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
1117 DefinedOrUnknownSVal V =
1118 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx, Ctx.IntTy, Count);
1123 if (!baseR->isBoundable())
1126 const TypedValueRegion *TR = cast<TypedValueRegion>(baseR);
1129 if (isInitiallyIncludedGlobalRegion(baseR)) {
1136 if (T->isRecordType()) {
1139 DefinedOrUnknownSVal V = svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
1145 if (
const ArrayType *AT = Ctx.getAsArrayType(T)) {
1146 bool doNotInvalidateSuperRegion = ITraits.hasTrait(
1150 if (doNotInvalidateSuperRegion) {
1157 NumElements = CAT->getSize().getZExtValue();
1159 goto conjure_default;
1160 QualType ElementTy = AT->getElementType();
1161 uint64_t ElemSize = Ctx.getTypeSize(ElementTy);
1162 const RegionOffset &RO = baseR->getAsOffset();
1163 const MemRegion *SuperR = baseR->getBaseRegion();
1164 if (RO.hasSymbolicOffset()) {
1168 AddToWorkList(SuperR);
1169 goto conjure_default;
1172 uint64_t LowerOffset = RO.getOffset();
1173 uint64_t UpperOffset = LowerOffset + *NumElements * ElemSize;
1174 bool UpperOverflow = UpperOffset < LowerOffset;
1179 goto conjure_default;
1181 const ClusterBindings *C = B.lookup(SuperR);
1183 goto conjure_default;
1185 for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E;
1187 const BindingKey &BK = I.getKey();
1194 ((*ROffset >= LowerOffset && *ROffset < UpperOffset) ||
1196 (*ROffset >= LowerOffset || *ROffset < UpperOffset)) ||
1197 (LowerOffset == UpperOffset && *ROffset == LowerOffset))) {
1198 B = B.removeBinding(I.getKey());
1201 SVal V = I.getData();
1202 const MemRegion *R = V.getAsRegion();
1203 if (R && isa<SymbolicRegion>(R))
1210 DefinedOrUnknownSVal V =
1211 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
1212 AT->getElementType(), Count);
1217 DefinedOrUnknownSVal V = svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
1220 B = B.addBinding(baseR, BindingKey::Direct, V);
1223 bool InvalidateRegionsWorker::isInitiallyIncludedGlobalRegion(
1224 const MemRegion *R) {
1225 switch (GlobalsFilter) {
1228 case GFK_SystemOnly:
1229 return isa<GlobalSystemSpaceRegion>(R->getMemorySpace());
1231 return isa<NonStaticGlobalSpaceRegion>(R->getMemorySpace());
1234 llvm_unreachable(
"unknown globals filter");
1237 bool InvalidateRegionsWorker::includeEntireMemorySpace(
const MemRegion *Base) {
1238 if (isInitiallyIncludedGlobalRegion(Base))
1241 const MemSpaceRegion *MemSpace = Base->getMemorySpace();
1242 return ITraits.hasTrait(MemSpace,
1251 RegionBindingsRef B,
1252 InvalidatedRegions *Invalidated) {
1255 const GlobalsSpaceRegion *GS = MRMgr.getGlobalsRegion(K);
1256 SVal V = svalBuilder.conjureSymbolVal( (
const void*) GS, Ex, LCtx,
1260 B = B.removeBinding(GS)
1266 Invalidated->push_back(GS);
1271 void RegionStoreManager::populateWorkList(InvalidateRegionsWorker &W,
1273 InvalidatedRegions *TopLevelRegions) {
1275 E = Values.end(); I != E; ++I) {
1278 V.getAs<nonloc::LazyCompoundVal>()) {
1280 const SValListTy &Vals = getInterestingValues(*LCS);
1282 for (SValListTy::const_iterator I = Vals.begin(),
1283 E = Vals.end(); I != E; ++I) {
1286 if (
const MemRegion *R = (*I).getAsRegion())
1292 if (
const MemRegion *R = V.getAsRegion()) {
1293 if (TopLevelRegions)
1294 TopLevelRegions->push_back(R);
1302 RegionStoreManager::invalidateRegions(
Store store,
1304 const Expr *Ex,
unsigned Count,
1308 RegionAndSymbolInvalidationTraits &ITraits,
1309 InvalidatedRegions *TopLevelRegions,
1310 InvalidatedRegions *Invalidated) {
1313 if (Call->isInSystemHeader())
1314 GlobalsFilter = GFK_SystemOnly;
1316 GlobalsFilter = GFK_All;
1318 GlobalsFilter = GFK_None;
1321 RegionBindingsRef B = getRegionBindings(store);
1322 InvalidateRegionsWorker W(*
this, StateMgr, B, Ex, Count, LCtx, IS, ITraits,
1323 Invalidated, GlobalsFilter);
1326 W.GenerateClusters();
1329 populateWorkList(W, Values, TopLevelRegions);
1334 B = W.getRegionBindings();
1340 switch (GlobalsFilter) {
1342 B = invalidateGlobalRegion(MemRegion::GlobalInternalSpaceRegionKind,
1343 Ex, Count, LCtx, B, Invalidated);
1345 case GFK_SystemOnly:
1346 B = invalidateGlobalRegion(MemRegion::GlobalSystemSpaceRegionKind,
1347 Ex, Count, LCtx, B, Invalidated);
1353 return StoreRef(B.asStore(), *
this);
1360 DefinedOrUnknownSVal
1364 SVal Size = cast<SubRegion>(R)->getExtent(svalBuilder);
1365 const llvm::APSInt *SizeInt = svalBuilder.getKnownValue(state, Size);
1367 return UnknownVal();
1371 if (Ctx.getAsVariableArrayType(EleTy)) {
1375 return UnknownVal();
1378 CharUnits EleSize = Ctx.getTypeSizeInChars(EleTy);
1383 return svalBuilder.makeIntVal(RegionSize / EleSize,
1384 svalBuilder.getArrayIndexType());
1397 SVal RegionStoreManager::ArrayToPointer(Loc Array,
QualType T) {
1398 if (Array.getAs<loc::ConcreteInt>())
1401 if (!Array.getAs<loc::MemRegionVal>())
1402 return UnknownVal();
1404 const SubRegion *R =
1405 cast<SubRegion>(Array.castAs<loc::MemRegionVal>().getRegion());
1406 NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex();
1407 return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, R, Ctx));
1414 SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L,
QualType T) {
1415 assert(!L.getAs<UnknownVal>() &&
"location unknown");
1416 assert(!L.getAs<UndefinedVal>() &&
"location undefined");
1424 if (L.getAs<loc::ConcreteInt>()) {
1425 return UnknownVal();
1427 if (!L.getAs<loc::MemRegionVal>()) {
1428 return UnknownVal();
1431 const MemRegion *MR = L.castAs<loc::MemRegionVal>().getRegion();
1433 if (isa<BlockDataRegion>(MR)) {
1434 return UnknownVal();
1437 if (!isa<TypedValueRegion>(MR)) {
1439 if (
const TypedRegion *TR = dyn_cast<TypedRegion>(MR))
1441 else if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
1444 assert(!T.
isNull() &&
"Unable to auto-detect binding type!");
1445 assert(!T->
isVoidType() &&
"Attempting to dereference a void pointer!");
1446 MR = GetElementZeroRegion(cast<SubRegion>(MR), T);
1448 T = cast<TypedValueRegion>(MR)->getValueType();
1453 const TypedValueRegion *R = cast<TypedValueRegion>(MR);
1458 if (RTy->isAnyComplexType())
1459 return UnknownVal();
1469 if (RTy->isStructureOrClassType())
1470 return getBindingForStruct(B, R);
1473 if (RTy->isUnionType())
1474 return createLazyBinding(B, R);
1476 if (RTy->isArrayType()) {
1477 if (RTy->isConstantArrayType())
1478 return getBindingForArray(B, R);
1480 return UnknownVal();
1484 if (RTy->isVectorType())
1485 return UnknownVal();
1487 if (
const FieldRegion* FR = dyn_cast<FieldRegion>(R))
1488 return CastRetrievedVal(getBindingForField(B, FR), FR, T);
1490 if (
const ElementRegion* ER = dyn_cast<ElementRegion>(R)) {
1496 return CastRetrievedVal(getBindingForElement(B, ER), ER, T);
1499 if (
const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) {
1506 return CastRetrievedVal(getBindingForObjCIvar(B, IVR), IVR, T);
1509 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
1516 return CastRetrievedVal(getBindingForVar(B, VR), VR, T);
1519 const SVal *V = B.lookup(R, BindingKey::Direct);
1528 if (R->hasStackNonParametersStorage()) {
1533 return UndefinedVal();
1537 return svalBuilder.getRegionValueSymbolVal(R);
1542 if (
const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R))
1543 RegionTy = TVR->getValueType();
1545 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
1546 RegionTy = SR->getSymbol()->getType();
1560 const SubRegion *R,
bool AllowSubregionBindings) {
1572 if (!RegionTy.
isNull() &&
1574 QualType SourceRegionTy = LCV->getRegion()->getValueType();
1575 if (!SVB.getContext().hasSameUnqualifiedType(RegionTy, SourceRegionTy))
1579 if (!AllowSubregionBindings) {
1585 if (Bindings.size() > 1)
1593 std::pair<Store, const SubRegion *>
1594 RegionStoreManager::findLazyBinding(RegionBindingsConstRef B,
1596 const SubRegion *originalRegion) {
1597 if (originalRegion != R) {
1600 return std::make_pair(V->getStore(), V->getRegion());
1603 typedef std::pair<Store, const SubRegion *> StoreRegionPair;
1604 StoreRegionPair Result = StoreRegionPair();
1606 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
1607 Result = findLazyBinding(B, cast<SubRegion>(ER->getSuperRegion()),
1611 Result.second = MRMgr.getElementRegionWithSuper(ER, Result.second);
1613 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
1614 Result = findLazyBinding(B, cast<SubRegion>(FR->getSuperRegion()),
1618 Result.second = MRMgr.getFieldRegionWithSuper(FR, Result.second);
1620 }
else if (
const CXXBaseObjectRegion *BaseReg =
1621 dyn_cast<CXXBaseObjectRegion>(R)) {
1624 Result = findLazyBinding(B, cast<SubRegion>(BaseReg->getSuperRegion()),
1628 Result.second = MRMgr.getCXXBaseObjectRegionWithSuper(BaseReg,
1635 SVal RegionStoreManager::getBindingForElement(RegionBindingsConstRef B,
1636 const ElementRegion* R) {
1638 if (isa<CompoundLiteralRegion>(R->getBaseRegion()))
1639 return UnknownVal();
1645 const MemRegion* superR = R->getSuperRegion();
1648 if (
const StringRegion *StrR = dyn_cast<StringRegion>(superR)) {
1651 QualType T = Ctx.getAsArrayType(StrR->getValueType())->getElementType();
1652 if (!Ctx.hasSameUnqualifiedType(T, R->getElementType()))
1653 return UnknownVal();
1656 SVal Idx = R->getIndex();
1658 int64_t
i = CI->getValue().getSExtValue();
1662 return UndefinedVal();
1669 return svalBuilder.makeIntVal(c, T);
1671 }
else if (
const VarRegion *VR = dyn_cast<VarRegion>(superR)) {
1673 const VarDecl *VD = VR->getDecl();
1677 if (
const auto *InitList = dyn_cast<InitListExpr>(Init)) {
1679 if (
auto CI = R->getIndex().getAs<nonloc::ConcreteInt>()) {
1680 int64_t
i = CI->getValue().getSExtValue();
1684 return UndefinedVal();
1686 if (
auto CAT = Ctx.getAsConstantArrayType(VD->
getType()))
1687 if (CAT->getSize().sle(i))
1688 return UndefinedVal();
1691 if (i >= InitList->getNumInits())
1692 return svalBuilder.makeZeroVal(R->getElementType());
1694 if (
const Expr *ElemInit = InitList->getInit(i))
1704 if (isa<CodeTextRegion>(superR))
1705 return UnknownVal();
1713 const RegionRawOffset &O = R->getAsArrayOffset();
1717 return UnknownVal();
1719 if (
const TypedValueRegion *baseR =
1720 dyn_cast_or_null<TypedValueRegion>(O.getRegion())) {
1721 QualType baseT = baseR->getValueType();
1723 QualType elemT = R->getElementType();
1725 if (Ctx.getTypeSizeInChars(baseT) >= Ctx.getTypeSizeInChars(elemT)) {
1727 if (
SymbolRef parentSym = V->getAsSymbol())
1728 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1730 if (V->isUnknownOrUndef())
1734 return UnknownVal();
1740 return getBindingForFieldOrElementCommon(B, R, R->getElementType());
1743 SVal RegionStoreManager::getBindingForField(RegionBindingsConstRef B,
1744 const FieldRegion* R) {
1759 const MemRegion* superR = R->getSuperRegion();
1760 if (
const auto *VR = dyn_cast<VarRegion>(superR)) {
1761 const VarDecl *VD = VR->getDecl();
1767 if (
const auto *InitList = dyn_cast<InitListExpr>(Init)) {
1768 if (Index < InitList->getNumInits()) {
1769 if (
const Expr *FieldInit = InitList->getInit(Index))
1773 return svalBuilder.makeZeroVal(Ty);
1778 return getBindingForFieldOrElementCommon(B, R, Ty);
1782 RegionStoreManager::getBindingForDerivedDefaultValue(RegionBindingsConstRef B,
1783 const MemRegion *superR,
1784 const TypedValueRegion *R,
1788 const SVal &val = D.getValue();
1789 if (
SymbolRef parentSym = val.getAsSymbol())
1790 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1792 if (val.isZeroConstant())
1793 return svalBuilder.makeZeroVal(Ty);
1795 if (val.isUnknownOrUndef())
1800 if (val.getAs<nonloc::LazyCompoundVal>() ||
1801 val.getAs<nonloc::CompoundVal>())
1804 llvm_unreachable(
"Unknown default value");
1810 SVal RegionStoreManager::getLazyBinding(
const SubRegion *LazyBindingRegion,
1811 RegionBindingsRef LazyBinding) {
1813 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(LazyBindingRegion))
1814 Result = getBindingForElement(LazyBinding, ER);
1816 Result = getBindingForField(LazyBinding,
1817 cast<FieldRegion>(LazyBindingRegion));
1833 if (Result.isUndef())
1834 Result = UnknownVal();
1840 RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
1841 const TypedValueRegion *R,
1848 Store lazyBindingStore =
nullptr;
1849 const SubRegion *lazyBindingRegion =
nullptr;
1850 std::tie(lazyBindingStore, lazyBindingRegion) = findLazyBinding(B, R, R);
1851 if (lazyBindingRegion)
1852 return getLazyBinding(lazyBindingRegion,
1853 getRegionBindings(lazyBindingStore));
1857 bool hasSymbolicIndex =
false;
1873 bool hasPartialLazyBinding =
false;
1875 const SubRegion *SR = R;
1877 const MemRegion *Base = SR->getSuperRegion();
1878 if (
Optional<SVal> D = getBindingForDerivedDefaultValue(B, Base, R, Ty)) {
1879 if (D->getAs<nonloc::LazyCompoundVal>()) {
1880 hasPartialLazyBinding =
true;
1887 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(Base)) {
1888 NonLoc index = ER->getIndex();
1889 if (!index.isConstant())
1890 hasSymbolicIndex =
true;
1895 SR = dyn_cast<SubRegion>(Base);
1898 if (R->hasStackNonParametersStorage()) {
1899 if (isa<ElementRegion>(R)) {
1902 if (
const TypedValueRegion *typedSuperR =
1903 dyn_cast<TypedValueRegion>(R->getSuperRegion())) {
1904 if (typedSuperR->getValueType()->isVectorType())
1905 return UnknownVal();
1913 if (hasSymbolicIndex)
1914 return UnknownVal();
1916 if (!hasPartialLazyBinding)
1917 return UndefinedVal();
1921 return svalBuilder.getRegionValueSymbolVal(R);
1924 SVal RegionStoreManager::getBindingForObjCIvar(RegionBindingsConstRef B,
1925 const ObjCIvarRegion* R) {
1930 const MemRegion *superR = R->getSuperRegion();
1934 if (
SymbolRef parentSym = V->getAsSymbol())
1935 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1938 return UnknownVal();
1941 return getBindingForLazySymbol(R);
1944 SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B,
1945 const VarRegion *R) {
1955 const VarDecl *VD = R->getDecl();
1956 const MemSpaceRegion *MS = R->getMemorySpace();
1959 if (isa<StackArgumentsSpaceRegion>(MS))
1960 return svalBuilder.getRegionValueSymbolVal(R);
1971 return UnknownVal();
1977 if (isa<UnknownSpaceRegion>(MS))
1978 return svalBuilder.getRegionValueSymbolVal(R);
1980 if (isa<GlobalsSpaceRegion>(MS)) {
1987 if (isa<StaticGlobalSpaceRegion>(MS))
1988 return svalBuilder.makeZeroVal(T);
1990 if (
Optional<SVal> V = getBindingForDerivedDefaultValue(B, MS, R, T)) {
1991 assert(!V->getAs<nonloc::LazyCompoundVal>());
1992 return V.getValue();
1995 return svalBuilder.getRegionValueSymbolVal(R);
1998 return UndefinedVal();
2001 SVal RegionStoreManager::getBindingForLazySymbol(
const TypedValueRegion *R) {
2003 return svalBuilder.getRegionValueSymbolVal(R);
2006 const RegionStoreManager::SValListTy &
2007 RegionStoreManager::getInterestingValues(nonloc::LazyCompoundVal LCV) {
2009 LazyBindingsMapTy::iterator I = LazyBindingsMap.find(LCV.getCVData());
2010 if (I != LazyBindingsMap.end())
2016 const SubRegion *LazyR = LCV.getRegion();
2017 RegionBindingsRef B = getRegionBindings(LCV.getStore());
2021 const ClusterBindings *Cluster = B.lookup(LazyR->getBaseRegion());
2023 return (LazyBindingsMap[LCV.getCVData()] = std::move(List));
2032 if (V.isUnknownOrUndef() || V.isConstant())
2036 V.getAs<nonloc::LazyCompoundVal>()) {
2037 const SValListTy &InnerList = getInterestingValues(*InnerLCV);
2038 List.insert(List.end(), InnerList.begin(), InnerList.end());
2045 return (LazyBindingsMap[LCV.getCVData()] = std::move(List));
2048 NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B,
2049 const TypedValueRegion *R) {
2054 return svalBuilder.makeLazyCompoundVal(StoreRef(B.asStore(), *
this), R);
2061 return CRD->getNumBases() == 0;
2065 SVal RegionStoreManager::getBindingForStruct(RegionBindingsConstRef B,
2066 const TypedValueRegion *R) {
2069 return UnknownVal();
2071 return createLazyBinding(B, R);
2074 SVal RegionStoreManager::getBindingForArray(RegionBindingsConstRef B,
2075 const TypedValueRegion *R) {
2076 assert(Ctx.getAsConstantArrayType(R->getValueType()) &&
2077 "Only constant array types can have compound bindings.");
2079 return createLazyBinding(B, R);
2082 bool RegionStoreManager::includedInBindings(
Store store,
2083 const MemRegion *region)
const {
2084 RegionBindingsRef B = getRegionBindings(store);
2085 region = region->getBaseRegion();
2088 if (B.lookup(region))
2092 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI) {
2093 const ClusterBindings &Cluster = RI.getData();
2094 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
2096 const SVal &D = CI.getData();
2097 if (
const MemRegion *R = D.getAsRegion())
2098 if (R->getBaseRegion() == region)
2110 StoreRef RegionStoreManager::killBinding(
Store ST, Loc L) {
2112 if (
const MemRegion* R = LV->getRegion())
2113 return StoreRef(getRegionBindings(ST).removeBinding(R)
2115 .getRootWithoutRetain(),
2118 return StoreRef(ST, *
this);
2122 RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) {
2123 if (L.getAs<loc::ConcreteInt>())
2127 const MemRegion *R = L.castAs<loc::MemRegionVal>().getRegion();
2130 if (
const TypedValueRegion* TR = dyn_cast<TypedValueRegion>(R)) {
2133 return bindArray(B, TR, V);
2135 return bindStruct(B, TR, V);
2137 return bindVector(B, TR, V);
2139 return bindAggregate(B, TR, V);
2142 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
2145 QualType T = SR->getSymbol()->getType();
2149 R = GetElementZeroRegion(SR, T);
2152 assert((!isa<CXXThisRegion>(R) || !B.lookup(R)) &&
2153 "'this' pointer is not an l-value and is not assignable");
2156 RegionBindingsRef NewB = removeSubRegionBindings(B, cast<SubRegion>(R));
2161 RegionStoreManager::setImplicitDefaultValue(RegionBindingsConstRef B,
2167 V = svalBuilder.makeNull();
2169 V = svalBuilder.makeZeroVal(T);
2173 V = svalBuilder.makeZeroVal(Ctx.IntTy);
2188 RegionStoreManager::bindArray(RegionBindingsConstRef B,
2189 const TypedValueRegion* R,
2192 const ArrayType *AT =cast<ArrayType>(Ctx.getCanonicalType(R->getValueType()));
2197 Size = CAT->getSize().getZExtValue();
2203 SVal V = getBinding(B.asStore(), *MRV, R->getValueType());
2204 return bindAggregate(B, R, V);
2208 if (Init.getAs<nonloc::LazyCompoundVal>())
2209 return bindAggregate(B, R, Init);
2211 if (Init.isUnknown())
2212 return bindAggregate(B, R, UnknownVal());
2215 const nonloc::CompoundVal& CV = Init.castAs<nonloc::CompoundVal>();
2219 RegionBindingsRef NewB(B);
2221 for (; Size.hasValue() ? i < Size.getValue() :
true ; ++
i, ++VI) {
2226 const NonLoc &Idx = svalBuilder.makeArrayIndex(i);
2227 const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx);
2230 NewB = bindStruct(NewB, ER, *VI);
2232 NewB = bindArray(NewB, ER, *VI);
2234 NewB = bind(NewB, loc::MemRegionVal(ER), *VI);
2240 if (!Size.hasValue() || i < Size.getValue())
2241 NewB = setImplicitDefaultValue(NewB, R, ElementTy);
2246 RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B,
2247 const TypedValueRegion* R,
2254 if (V.getAs<nonloc::LazyCompoundVal>() || V.getAs<nonloc::SymbolVal>())
2255 return bindAggregate(B, R, V);
2260 if (!V.getAs<nonloc::CompoundVal>()) {
2261 return bindAggregate(B, R, UnknownVal());
2264 QualType ElemType = VT->getElementType();
2265 nonloc::CompoundVal CV = V.
castAs<nonloc::CompoundVal>();
2267 unsigned index = 0, numElements = VT->getNumElements();
2268 RegionBindingsRef NewB(B);
2270 for ( ; index != numElements ; ++index) {
2274 NonLoc Idx = svalBuilder.makeArrayIndex(index);
2275 const ElementRegion *ER = MRMgr.getElementRegion(ElemType, Idx, R, Ctx);
2278 NewB = bindArray(NewB, ER, *VI);
2280 NewB = bindStruct(NewB, ER, *VI);
2282 NewB = bind(NewB, loc::MemRegionVal(ER), *VI);
2288 RegionStoreManager::tryBindSmallStruct(RegionBindingsConstRef B,
2289 const TypedValueRegion *R,
2291 nonloc::LazyCompoundVal LCV) {
2294 if (
const CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(RD))
2295 if (Class->getNumBases() != 0 || Class->getNumVBases() != 0)
2298 for (
const auto *FD : RD->
fields()) {
2299 if (FD->isUnnamedBitfield())
2304 if (Fields.size() == SmallStructLimit)
2311 Fields.push_back(FD);
2314 RegionBindingsRef NewB = B;
2316 for (FieldVector::iterator I = Fields.begin(), E = Fields.end(); I != E; ++I){
2317 const FieldRegion *SourceFR = MRMgr.getFieldRegion(*I, LCV.getRegion());
2318 SVal V = getBindingForField(getRegionBindings(LCV.getStore()), SourceFR);
2320 const FieldRegion *DestFR = MRMgr.getFieldRegion(*I, R);
2321 NewB = bind(NewB, loc::MemRegionVal(DestFR), V);
2327 RegionBindingsRef RegionStoreManager::bindStruct(RegionBindingsConstRef B,
2328 const TypedValueRegion* R,
2330 if (!Features.supportsFields())
2339 if (!RD->isCompleteDefinition())
2344 V.getAs<nonloc::LazyCompoundVal>()) {
2347 return bindAggregate(B, R, V);
2349 if (V.getAs<nonloc::SymbolVal>())
2350 return bindAggregate(B, R, V);
2355 if (V.isUnknown() || !V.getAs<nonloc::CompoundVal>())
2356 return bindAggregate(B, R, UnknownVal());
2374 const nonloc::CompoundVal& CV = V.castAs<nonloc::CompoundVal>();
2377 RegionBindingsRef NewB(B);
2381 if (
const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
2389 assert((CRD->isAggregate() || (Ctx.getLangOpts().ObjC && VI == VE)) &&
2390 "Non-aggregates are constructed with a constructor!");
2392 for (
const auto &B : CRD->bases()) {
2394 assert(!B.isVirtual() &&
"Aggregates cannot have virtual base classes!");
2403 assert(BRD &&
"Base classes must be C++ classes!");
2405 const CXXBaseObjectRegion *BR =
2406 MRMgr.getCXXBaseObjectRegion(BRD, R,
false);
2408 NewB = bindStruct(NewB, BR, *VI);
2416 for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI) {
2422 if (FI->isUnnamedBitfield())
2426 const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
2429 NewB = bindArray(NewB, FR, *VI);
2431 NewB = bindStruct(NewB, FR, *VI);
2433 NewB = bind(NewB, loc::MemRegionVal(FR), *VI);
2440 svalBuilder.makeIntVal(0,
false));
2447 RegionStoreManager::bindAggregate(RegionBindingsConstRef B,
2448 const TypedRegion *R,
2460 class RemoveDeadBindingsWorker
2461 :
public ClusterAnalysis<RemoveDeadBindingsWorker> {
2463 SymbolReaper &SymReaper;
2467 RemoveDeadBindingsWorker(RegionStoreManager &rm,
2468 ProgramStateManager &stateMgr,
2469 RegionBindingsRef
b, SymbolReaper &symReaper,
2471 : ClusterAnalysis<RemoveDeadBindingsWorker>(rm, stateMgr,
b),
2472 SymReaper(symReaper), CurrentLCtx(LCtx) {}
2475 void VisitAddedToCluster(
const MemRegion *baseR,
const ClusterBindings &C);
2476 void VisitCluster(
const MemRegion *baseR,
const ClusterBindings *C);
2477 using ClusterAnalysis<RemoveDeadBindingsWorker>::VisitCluster;
2479 using ClusterAnalysis::AddToWorkList;
2481 bool AddToWorkList(
const MemRegion *R);
2483 bool UpdatePostponed();
2484 void VisitBinding(SVal V);
2488 bool RemoveDeadBindingsWorker::AddToWorkList(
const MemRegion *R) {
2489 const MemRegion *BaseR = R->getBaseRegion();
2490 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
2493 void RemoveDeadBindingsWorker::VisitAddedToCluster(
const MemRegion *baseR,
2494 const ClusterBindings &C) {
2496 if (
const VarRegion *VR = dyn_cast<VarRegion>(baseR)) {
2497 if (SymReaper.isLive(VR))
2498 AddToWorkList(baseR, &C);
2503 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
2504 if (SymReaper.isLive(SR->getSymbol()))
2505 AddToWorkList(SR, &C);
2507 Postponed.push_back(SR);
2512 if (isa<NonStaticGlobalSpaceRegion>(baseR)) {
2513 AddToWorkList(baseR, &C);
2518 if (
const CXXThisRegion *TR = dyn_cast<CXXThisRegion>(baseR)) {
2519 const auto *StackReg =
2520 cast<StackArgumentsSpaceRegion>(TR->getSuperRegion());
2523 (RegCtx == CurrentLCtx || RegCtx->isParentOf(CurrentLCtx)))
2524 AddToWorkList(TR, &C);
2528 void RemoveDeadBindingsWorker::VisitCluster(
const MemRegion *baseR,
2529 const ClusterBindings *C) {
2535 if (
const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(baseR))
2536 SymReaper.markLive(SymR->getSymbol());
2538 for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E; ++I) {
2540 SymReaper.markElementIndicesLive(I.getKey().getRegion());
2542 VisitBinding(I.getData());
2546 void RemoveDeadBindingsWorker::VisitBinding(SVal V) {
2549 V.getAs<nonloc::LazyCompoundVal>()) {
2551 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
2553 for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
2562 if (
const MemRegion *R = V.getAsRegion()) {
2564 SymReaper.markLive(R);
2567 if (
const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(R)) {
2568 BlockDataRegion::referenced_vars_iterator I = BR->referenced_vars_begin(),
2569 E = BR->referenced_vars_end();
2570 for ( ; I != E; ++I)
2571 AddToWorkList(I.getCapturedRegion());
2577 for (
auto SI = V.symbol_begin(), SE = V.symbol_end(); SI!=SE; ++SI)
2578 SymReaper.markLive(*SI);
2581 bool RemoveDeadBindingsWorker::UpdatePostponed() {
2584 bool Changed =
false;
2586 for (
auto I = Postponed.begin(), E = Postponed.end(); I != E; ++I) {
2587 if (
const SymbolicRegion *SR = *I) {
2588 if (SymReaper.isLive(SR->getSymbol())) {
2589 Changed |= AddToWorkList(SR);
2598 StoreRef RegionStoreManager::removeDeadBindings(
Store store,
2600 SymbolReaper& SymReaper) {
2601 RegionBindingsRef B = getRegionBindings(store);
2602 RemoveDeadBindingsWorker W(*
this, StateMgr, B, SymReaper, LCtx);
2603 W.GenerateClusters();
2607 E = SymReaper.region_end(); I != E; ++I) {
2608 W.AddToWorkList(*I);
2611 do W.RunWorkList();
while (W.UpdatePostponed());
2616 for (RegionBindingsRef::iterator I = B.begin(), E = B.end(); I != E; ++I) {
2617 const MemRegion *Base = I.getKey();
2621 if (!W.isVisited(Base))
2625 return StoreRef(B.asStore(), *
this);
2632 void RegionStoreManager::printJson(raw_ostream &Out,
Store S,
const char *NL,
2633 unsigned int Space,
bool IsDot)
const {
2634 RegionBindingsRef Bindings = getRegionBindings(S);
2636 Indent(Out, Space, IsDot) <<
"\"store\": ";
2638 if (Bindings.isEmpty()) {
2639 Out <<
"null," << NL;
2643 Out <<
"{ \"pointer\": \"" << Bindings.asStore() <<
"\", \"items\": [" << NL;
2644 Bindings.printJson(Out, NL, Space + 1, IsDot);
2645 Indent(Out, Space, IsDot) <<
"]}," << NL;
A (possibly-)qualified type.
static void getSymbolicOffsetFields(BindingKey K, FieldVector &Fields)
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
bool operator==(CanQual< T > x, CanQual< U > y)
llvm::DenseSet< SymbolRef > InvalidatedSymbols
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
const SymExpr * SymbolRef
internal::Matcher< Stmt > StatementMatcher
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
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.
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 T * getAs() const
Member-template getAs<specific type>'.
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
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
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
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.
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
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
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.
llvm::ImmutableMapRef< BindingKey, SVal > ClusterBindingsRef
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
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 isAnyPointerType() const
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
bool isVectorType() const
Tells that a region's contents is not changed.
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, 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...
const StackFrameContext * getStackFrame() const
std::pair< BindingKey, SVal > BindingPair
Stores options for the analyzer from the command line.
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.
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
const RegionBindingsRef & RegionBindingsConstRef
Represents the canonical version of C arrays with a specified constant size.