28 #include "llvm/ADT/ImmutableList.h"
29 #include "llvm/ADT/ImmutableMap.h"
30 #include "llvm/ADT/Optional.h"
31 #include "llvm/Support/raw_ostream.h"
33 using namespace clang;
43 enum Kind { Default = 0x0, Direct = 0x1 };
45 enum { Symbolic = 0x2 };
47 llvm::PointerIntPair<const MemRegion *, 2>
P;
53 :
P(r, k | Symbolic), Data(reinterpret_cast<uintptr_t>(Base)) {
54 assert(r && Base &&
"Must have known regions.");
55 assert(getConcreteOffsetRegion() == Base &&
"Failed to store base region");
59 explicit BindingKey(
const MemRegion *r, uint64_t offset,
Kind k)
60 :
P(r, k), Data(offset) {
61 assert(r &&
"Must have known regions.");
62 assert(getOffset() == offset &&
"Failed to store offset");
63 assert((r == r->
getBaseRegion() || isa<ObjCIvarRegion>(r)) &&
"Not a base");
67 bool isDirect()
const {
return P.getInt() & Direct; }
68 bool hasSymbolicOffset()
const {
return P.getInt() & Symbolic; }
70 const MemRegion *getRegion()
const {
return P.getPointer(); }
71 uint64_t getOffset()
const {
72 assert(!hasSymbolicOffset());
76 const SubRegion *getConcreteOffsetRegion()
const {
77 assert(hasSymbolicOffset());
78 return reinterpret_cast<const SubRegion *
>(
static_cast<uintptr_t
>(Data));
82 if (hasSymbolicOffset())
87 void Profile(llvm::FoldingSetNodeID&
ID)
const {
88 ID.AddPointer(
P.getOpaqueValue());
95 if (
P.getOpaqueValue() < X.P.getOpaqueValue())
97 if (
P.getOpaqueValue() > X.P.getOpaqueValue())
103 return P.getOpaqueValue() == X.P.getOpaqueValue() &&
114 return BindingKey(cast<SubRegion>(R), cast<SubRegion>(RO.
getRegion()), k);
122 os <<
'(' << K.getRegion();
123 if (!K.hasSymbolicOffset())
124 os <<
',' << K.getOffset();
125 os <<
',' << (K.isDirect() ?
"direct" :
"default")
130 template <
typename T>
struct isPodLike;
132 static const bool value =
true;
150 class RegionBindingsRef :
public llvm::ImmutableMapRef<const MemRegion *,
152 ClusterBindings::Factory &CBFactory;
154 typedef llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>
157 RegionBindingsRef(ClusterBindings::Factory &CBFactory,
158 const RegionBindings::TreeTy *T,
159 RegionBindings::TreeTy::Factory *F)
160 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(T, F),
161 CBFactory(CBFactory) {}
163 RegionBindingsRef(
const ParentTy &
P, ClusterBindings::Factory &CBFactory)
164 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(
P),
165 CBFactory(CBFactory) {}
167 RegionBindingsRef add(key_type_ref K, data_type_ref D)
const {
168 return RegionBindingsRef(static_cast<const ParentTy*>(
this)->add(K, D),
172 RegionBindingsRef
remove(key_type_ref K)
const {
173 return RegionBindingsRef(static_cast<const ParentTy*>(
this)->
remove(K),
177 RegionBindingsRef addBinding(BindingKey K,
SVal V)
const;
179 RegionBindingsRef addBinding(
const MemRegion *R,
180 BindingKey::Kind k,
SVal V)
const;
182 RegionBindingsRef &operator=(
const RegionBindingsRef &X) {
183 *
static_cast<ParentTy*
>(
this) = X;
187 const SVal *lookup(BindingKey K)
const;
188 const SVal *lookup(
const MemRegion *R, BindingKey::Kind k)
const;
190 return static_cast<const ParentTy*
>(
this)->lookup(R);
193 RegionBindingsRef removeBinding(BindingKey K);
195 RegionBindingsRef removeBinding(
const MemRegion *R,
198 RegionBindingsRef removeBinding(
const MemRegion *R) {
199 return removeBinding(R, BindingKey::Direct).
200 removeBinding(R, BindingKey::Default);
210 Store asStore()
const {
211 return asImmutableMap().getRootWithoutRetain();
214 void dump(raw_ostream &OS,
const char *nl)
const {
215 for (iterator I = begin(), E = end(); I != E; ++I) {
217 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
219 OS <<
' ' << CI.getKey() <<
" : " << CI.getData() << nl;
225 LLVM_DUMP_METHOD
void dump()
const {
dump(llvm::errs(),
"\n"); }
238 if (TR->getValueType()->isUnionType())
244 RegionBindingsRef RegionBindingsRef::addBinding(BindingKey K,
SVal V)
const {
245 const MemRegion *Base = K.getBaseRegion();
249 : CBFactory.getEmptyMap());
252 return add(Base, NewCluster);
256 RegionBindingsRef RegionBindingsRef::addBinding(
const MemRegion *R,
262 const SVal *RegionBindingsRef::lookup(BindingKey K)
const {
266 return Cluster->lookup(K);
270 BindingKey::Kind k)
const {
274 RegionBindingsRef RegionBindingsRef::removeBinding(BindingKey K) {
275 const MemRegion *Base = K.getBaseRegion();
281 if (NewCluster.isEmpty())
283 return add(Base, NewCluster);
286 RegionBindingsRef RegionBindingsRef::removeBinding(
const MemRegion *R,
296 struct minimal_features_tag {};
297 struct maximal_features_tag {};
299 class RegionStoreFeatures {
302 RegionStoreFeatures(minimal_features_tag) :
303 SupportsFields(
false) {}
305 RegionStoreFeatures(maximal_features_tag) :
306 SupportsFields(
true) {}
308 void enableFields(
bool t) { SupportsFields = t; }
310 bool supportsFields()
const {
return SupportsFields; }
319 class invalidateRegionsWorker;
323 const RegionStoreFeatures Features;
325 RegionBindings::Factory RBFactory;
326 mutable ClusterBindings::Factory CBFactory;
328 typedef std::vector<SVal> SValListTy;
331 SValListTy> LazyBindingsMapTy;
332 LazyBindingsMapTy LazyBindingsMap;
342 unsigned SmallStructLimit;
346 void populateWorkList(invalidateRegionsWorker &W,
348 InvalidatedRegions *TopLevelRegions);
353 RBFactory(mgr.getAllocator()), CBFactory(mgr.getAllocator()),
354 SmallStructLimit(0) {
355 if (
SubEngine *Eng = StateMgr.getOwningEngine()) {
378 return StoreRef(RBFactory.getEmptyMap().getRootWithoutRetain(), *
this);
389 InvalidatedRegions *Invalidated);
398 InvalidatedRegions *Invalidated,
399 InvalidatedRegions *InvalidatedTopLevel)
override;
410 return StoreRef(bind(getRegionBindings(store), LV, V).asStore(), *
this);
417 RegionBindingsRef B = getRegionBindings(store);
418 assert(!B.lookup(R, BindingKey::Direct));
422 const SubRegion *SR = cast<SubRegion>(R);
425 "A default value must come from a super-region");
426 B = removeSubRegionBindings(B, SR);
428 B = B.addBinding(Key, V);
431 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *
this);
472 void incrementReferenceCount(
Store store)
override {
473 getRegionBindings(store).manualRetain();
479 void decrementReferenceCount(
Store store)
override {
480 getRegionBindings(store).manualRelease();
483 bool includedInBindings(
Store store,
const MemRegion *region)
const override;
499 return getBinding(getRegionBindings(S), L, T);
519 RegionBindingsRef LazyBinding);
544 std::pair<Store, const SubRegion *>
578 RegionBindingsRef getRegionBindings(
Store store)
const {
579 return RegionBindingsRef(CBFactory,
580 static_cast<const RegionBindings::TreeTy*>(store),
581 RBFactory.getTreeFactory());
584 void print(
Store store, raw_ostream &Out,
const char* nl,
585 const char *sep)
override;
587 void iterBindings(
Store store, BindingsHandler& f)
override {
588 RegionBindingsRef B = getRegionBindings(store);
589 for (RegionBindingsRef::iterator I = B.begin(), E = B.end(); I != E; ++I) {
591 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
593 const BindingKey &K = CI.getKey();
596 if (
const SubRegion *R = dyn_cast<SubRegion>(K.getRegion())) {
598 if (!f.HandleBinding(*
this, store, R, CI.getData()))
612 std::unique_ptr<StoreManager>
614 RegionStoreFeatures F = maximal_features_tag();
615 return llvm::make_unique<RegionStoreManager>(StMgr, F);
618 std::unique_ptr<StoreManager>
620 RegionStoreFeatures F = minimal_features_tag();
621 F.enableFields(
true);
622 return llvm::make_unique<RegionStoreManager>(StMgr, F);
642 template <
typename DERIVED>
643 class ClusterAnalysis {
645 typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
646 typedef const MemRegion * WorkListElement;
649 llvm::SmallPtrSet<const ClusterBindings *, 16> Visited;
653 RegionStoreManager &RM;
669 bool isInitiallyIncludedGlobalRegion(
const MemRegion *R) {
670 switch (GlobalsFilter) {
679 llvm_unreachable(
"unknown globals filter");
685 : RM(rm), Ctx(StateMgr.getContext()),
686 svalBuilder(StateMgr.getSValBuilder()),
687 B(b), GlobalsFilter(GFK) {}
689 RegionBindingsRef getRegionBindings()
const {
return B; }
692 return Visited.count(getCluster(R));
695 void GenerateClusters() {
697 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end();
702 assert(!Cluster.isEmpty() &&
"Empty clusters should be removed");
703 static_cast<DERIVED*
>(
this)->VisitAddedToCluster(Base, Cluster);
706 if (isInitiallyIncludedGlobalRegion(Base))
707 AddToWorkList(WorkListElement(Base), &Cluster);
712 if (C && !Visited.insert(C).second)
720 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
724 while (!WL.empty()) {
725 WorkListElement E = WL.pop_back_val();
728 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, getCluster(BaseR));
737 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, C);
746 bool RegionStoreManager::scanReachableSymbols(
Store S,
const MemRegion *R,
748 assert(R == R->
getBaseRegion() &&
"Should only be called for base regions");
749 RegionBindingsRef B = getRegionBindings(S);
755 for (ClusterBindings::iterator RI = Cluster->begin(), RE = Cluster->end();
757 if (!Callbacks.
scan(RI.getData()))
771 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
773 const MemRegion *Base = K.getConcreteOffsetRegion();
777 if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R))
779 Fields.push_back(FR->getDecl());
781 R = cast<SubRegion>(R)->getSuperRegion();
786 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
794 ptrdiff_t Delta = FieldsInBindingKey.size() - Fields.size();
796 return std::equal(FieldsInBindingKey.begin() + Delta,
797 FieldsInBindingKey.end(),
800 return std::equal(FieldsInBindingKey.begin(), FieldsInBindingKey.end(),
801 Fields.begin() - Delta);
817 bool IncludeAllDefaultBindings) {
819 if (TopKey.hasSymbolicOffset()) {
821 Top = cast<SubRegion>(TopKey.getConcreteOffsetRegion());
826 uint64_t Length = UINT64_MAX;
830 const llvm::APSInt &ExtentInt = ExtentCI->getValue();
831 assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned());
834 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(Top)) {
835 if (FR->getDecl()->isBitField())
836 Length = FR->getDecl()->getBitWidthValue(SVB.
getContext());
839 for (ClusterBindings::iterator I = Cluster.begin(), E = Cluster.end();
841 BindingKey NextKey = I.getKey();
842 if (NextKey.getRegion() == TopKey.getRegion()) {
848 if (NextKey.getOffset() > TopKey.getOffset() &&
849 NextKey.getOffset() - TopKey.getOffset() < Length) {
852 Bindings.push_back(*I);
854 }
else if (NextKey.getOffset() == TopKey.getOffset()) {
861 if (IncludeAllDefaultBindings || NextKey.isDirect())
862 Bindings.push_back(*I);
865 }
else if (NextKey.hasSymbolicOffset()) {
866 const MemRegion *Base = NextKey.getConcreteOffsetRegion();
871 if (IncludeAllDefaultBindings || NextKey.isDirect())
873 Bindings.push_back(*I);
874 }
else if (
const SubRegion *BaseSR = dyn_cast<SubRegion>(Base)) {
879 Bindings.push_back(*I);
888 const SubRegion *Top,
bool IncludeAllDefaultBindings) {
891 IncludeAllDefaultBindings);
898 const MemRegion *ClusterHead = TopKey.getBaseRegion();
900 if (Top == ClusterHead) {
902 return B.remove(Top);
909 if (TopKey.hasSymbolicOffset()) {
910 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
911 return B.addBinding(Concrete, BindingKey::Default,
UnknownVal());
924 Result =
Result.remove(I->first);
930 if (TopKey.hasSymbolicOffset()) {
931 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
937 return B.remove(ClusterHead);
938 return B.add(ClusterHead,
Result.asImmutableMap());
942 class invalidateRegionsWorker :
public ClusterAnalysis<invalidateRegionsWorker>
951 invalidateRegionsWorker(RegionStoreManager &rm,
954 const Expr *ex,
unsigned count,
960 : ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b, GFK),
961 Ex(ex),
Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r){}
964 void VisitBinding(
SVal V);
968 void invalidateRegionsWorker::VisitBinding(
SVal V) {
982 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
984 for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
993 void invalidateRegionsWorker::VisitCluster(
const MemRegion *baseR,
996 bool PreserveRegionsContents =
997 ITraits.hasTrait(baseR,
1001 for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E; ++I)
1002 VisitBinding(I.getData());
1005 if (!PreserveRegionsContents)
1006 B = B.remove(baseR);
1013 BI = BR->referenced_vars_begin(), BE = BR->referenced_vars_end() ;
1015 const VarRegion *VR = BI.getCapturedRegion();
1038 IS.insert(SR->getSymbol());
1041 if (PreserveRegionsContents)
1046 Regions->push_back(baseR);
1048 if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
1052 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx, Ctx.IntTy,
Count);
1053 B = B.addBinding(baseR, BindingKey::Default, V);
1063 if (isInitiallyIncludedGlobalRegion(baseR)) {
1070 if (T->isStructureOrClassType()) {
1075 B = B.addBinding(baseR, BindingKey::Default, V);
1079 if (
const ArrayType *AT = Ctx.getAsArrayType(T)) {
1082 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
1083 AT->getElementType(),
Count);
1084 B = B.addBinding(baseR, BindingKey::Default, V);
1091 B = B.addBinding(baseR, BindingKey::Direct, V);
1099 RegionBindingsRef B,
1100 InvalidatedRegions *Invalidated) {
1104 SVal V = svalBuilder.conjureSymbolVal( (
const void*) GS, Ex, LCtx,
1108 B = B.removeBinding(GS)
1114 Invalidated->push_back(GS);
1119 void RegionStoreManager::populateWorkList(invalidateRegionsWorker &W,
1121 InvalidatedRegions *TopLevelRegions) {
1123 E = Values.end(); I != E; ++I) {
1128 const SValListTy &Vals = getInterestingValues(*LCS);
1130 for (SValListTy::const_iterator I = Vals.begin(),
1131 E = Vals.end(); I != E; ++I) {
1134 if (
const MemRegion *R = (*I).getAsRegion())
1141 if (TopLevelRegions)
1142 TopLevelRegions->push_back(R);
1150 RegionStoreManager::invalidateRegions(
Store store,
1152 const Expr *Ex,
unsigned Count,
1157 InvalidatedRegions *TopLevelRegions,
1158 InvalidatedRegions *Invalidated) {
1162 GlobalsFilter = GFK_SystemOnly;
1164 GlobalsFilter = GFK_All;
1166 GlobalsFilter = GFK_None;
1169 RegionBindingsRef B = getRegionBindings(store);
1170 invalidateRegionsWorker W(*
this, StateMgr, B, Ex, Count, LCtx, IS, ITraits,
1171 Invalidated, GlobalsFilter);
1174 W.GenerateClusters();
1177 populateWorkList(W, Values, TopLevelRegions);
1182 B = W.getRegionBindings();
1188 switch (GlobalsFilter) {
1191 Ex, Count, LCtx, B, Invalidated);
1193 case GFK_SystemOnly:
1195 Ex, Count, LCtx, B, Invalidated);
1201 return StoreRef(B.asStore(), *
this);
1212 SVal Size = cast<SubRegion>(R)->getExtent(svalBuilder);
1213 const llvm::APSInt *SizeInt = svalBuilder.getKnownValue(state, Size);
1219 if (Ctx.getAsVariableArrayType(EleTy)) {
1226 CharUnits EleSize = Ctx.getTypeSizeInChars(EleTy);
1231 return svalBuilder.makeIntVal(RegionSize / EleSize,
false);
1249 NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex();
1276 if (isa<AllocaRegion>(MR) ||
1277 isa<SymbolicRegion>(MR) ||
1278 isa<CodeTextRegion>(MR)) {
1280 if (
const TypedRegion *TR = dyn_cast<TypedRegion>(MR))
1287 MR = GetElementZeroRegion(MR, T);
1297 if (RTy->isAnyComplexType())
1308 if (RTy->isStructureOrClassType())
1309 return getBindingForStruct(B, R);
1312 if (RTy->isUnionType())
1313 return createLazyBinding(B, R);
1315 if (RTy->isArrayType()) {
1316 if (RTy->isConstantArrayType())
1317 return getBindingForArray(B, R);
1323 if (RTy->isVectorType())
1326 if (
const FieldRegion* FR = dyn_cast<FieldRegion>(R))
1327 return CastRetrievedVal(getBindingForField(B, FR), FR, T,
false);
1335 return CastRetrievedVal(getBindingForElement(B, ER), ER, T,
false);
1345 return CastRetrievedVal(getBindingForObjCIvar(B, IVR), IVR, T,
false);
1348 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
1355 return CastRetrievedVal(getBindingForVar(B, VR), VR, T,
false);
1358 const SVal *V = B.lookup(R, BindingKey::Direct);
1376 return svalBuilder.getRegionValueSymbolVal(R);
1382 RegionTy = TVR->getValueType();
1385 RegionTy = SR->getSymbol()->getType();
1399 const SubRegion *R,
bool AllowSubregionBindings) {
1411 if (!RegionTy.
isNull() &&
1413 QualType SourceRegionTy = LCV->getRegion()->getValueType();
1418 if (!AllowSubregionBindings) {
1424 if (Bindings.size() > 1)
1432 std::pair<Store, const SubRegion *>
1436 if (originalRegion != R) {
1439 return std::make_pair(V->getStore(), V->getRegion());
1442 typedef std::pair<Store, const SubRegion *> StoreRegionPair;
1443 StoreRegionPair
Result = StoreRegionPair();
1446 Result = findLazyBinding(B, cast<SubRegion>(ER->getSuperRegion()),
1450 Result.second = MRMgr.getElementRegionWithSuper(ER, Result.second);
1452 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
1453 Result = findLazyBinding(B, cast<SubRegion>(FR->getSuperRegion()),
1457 Result.second = MRMgr.getFieldRegionWithSuper(FR, Result.second);
1460 dyn_cast<CXXBaseObjectRegion>(R)) {
1463 Result = findLazyBinding(B, cast<SubRegion>(BaseReg->getSuperRegion()),
1467 Result.second = MRMgr.getCXXBaseObjectRegionWithSuper(BaseReg,
1487 if (
const StringRegion *StrR=dyn_cast<StringRegion>(superR)) {
1497 int64_t i = CI->getValue().getSExtValue();
1507 char c = (i >= length) ?
'\0' : Str->
getCodeUnit(i);
1508 return svalBuilder.makeIntVal(c, T);
1513 if (isa<CodeTextRegion>(superR))
1529 dyn_cast_or_null<TypedValueRegion>(O.
getRegion())) {
1530 QualType baseT = baseR->getValueType();
1534 if (Ctx.getTypeSizeInChars(baseT) >= Ctx.getTypeSizeInChars(elemT)) {
1537 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1549 return getBindingForFieldOrElementCommon(B, R, R->
getElementType());
1560 return getBindingForFieldOrElementCommon(B, R, Ty);
1570 const SVal &val = D.getValue();
1572 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1575 return svalBuilder.makeZeroVal(Ty);
1585 llvm_unreachable(
"Unknown default value");
1591 SVal RegionStoreManager::getLazyBinding(
const SubRegion *LazyBindingRegion,
1592 RegionBindingsRef LazyBinding) {
1594 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(LazyBindingRegion))
1595 Result = getBindingForElement(LazyBinding, ER);
1597 Result = getBindingForField(LazyBinding,
1598 cast<FieldRegion>(LazyBindingRegion));
1629 Store lazyBindingStore =
nullptr;
1630 const SubRegion *lazyBindingRegion =
nullptr;
1631 std::tie(lazyBindingStore, lazyBindingRegion) = findLazyBinding(B, R, R);
1632 if (lazyBindingRegion)
1633 return getLazyBinding(lazyBindingRegion,
1634 getRegionBindings(lazyBindingStore));
1638 bool hasSymbolicIndex =
false;
1654 bool hasPartialLazyBinding =
false;
1659 if (
Optional<SVal> D = getBindingForDerivedDefaultValue(B, Base, R, Ty)) {
1661 hasPartialLazyBinding =
true;
1668 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(Base)) {
1669 NonLoc index = ER->getIndex();
1671 hasSymbolicIndex =
true;
1680 if (isa<ElementRegion>(R)) {
1685 if (typedSuperR->getValueType()->isVectorType())
1694 if (hasSymbolicIndex)
1697 if (!hasPartialLazyBinding)
1702 return svalBuilder.getRegionValueSymbolVal(R);
1716 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1722 return getBindingForLazySymbol(R);
1737 if (isa<StackArgumentsSpaceRegion>(MS))
1738 return svalBuilder.getRegionValueSymbolVal(R);
1748 if (isa<UnknownSpaceRegion>(MS))
1749 return svalBuilder.getRegionValueSymbolVal(R);
1751 if (isa<GlobalsSpaceRegion>(MS)) {
1756 if (isa<StaticGlobalSpaceRegion>(MS))
1757 return svalBuilder.makeZeroVal(T);
1759 if (
Optional<SVal> V = getBindingForDerivedDefaultValue(B, MS, R, T)) {
1761 return V.getValue();
1764 return svalBuilder.getRegionValueSymbolVal(R);
1772 return svalBuilder.getRegionValueSymbolVal(R);
1775 const RegionStoreManager::SValListTy &
1778 LazyBindingsMapTy::iterator I = LazyBindingsMap.find(LCV.
getCVData());
1779 if (I != LazyBindingsMap.end())
1786 RegionBindingsRef B = getRegionBindings(LCV.
getStore());
1792 return (LazyBindingsMap[LCV.
getCVData()] = std::move(List));
1806 const SValListTy &InnerList = getInterestingValues(*InnerLCV);
1807 List.insert(List.end(), InnerList.begin(), InnerList.end());
1814 return (LazyBindingsMap[LCV.
getCVData()] = std::move(List));
1823 return svalBuilder.makeLazyCompoundVal(
StoreRef(B.asStore(), *
this), R);
1830 return CRD->getNumBases() == 0;
1840 return createLazyBinding(B, R);
1845 assert(Ctx.getAsConstantArrayType(R->
getValueType()) &&
1846 "Only constant array types can have compound bindings.");
1848 return createLazyBinding(B, R);
1851 bool RegionStoreManager::includedInBindings(
Store store,
1853 RegionBindingsRef B = getRegionBindings(store);
1857 if (B.lookup(region))
1861 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI) {
1863 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
1865 const SVal &D = CI.getData();
1881 if (
const MemRegion* R = LV->getRegion())
1882 return StoreRef(getRegionBindings(ST).removeBinding(R)
1884 .getRootWithoutRetain(),
1902 return bindArray(B, TR, V);
1904 return bindStruct(B, TR, V);
1906 return bindVector(B, TR, V);
1908 return bindAggregate(B, TR, V);
1914 QualType T = SR->getSymbol()->getType();
1918 R = GetElementZeroRegion(SR, T);
1922 RegionBindingsRef NewB = removeSubRegionBindings(B, cast<SubRegion>(R));
1933 V = svalBuilder.makeNull();
1935 V = svalBuilder.makeZeroVal(T);
1939 V = svalBuilder.makeZeroVal(Ctx.IntTy);
1950 return B.addBinding(R, BindingKey::Default, V);
1963 Size = CAT->getSize().getZExtValue();
1967 const StringRegion *S = cast<StringRegion>(MRV->getRegion());
1970 StoreRef store(B.asStore(), *
this);
1973 return bindAggregate(B, R, LCV);
1978 return bindAggregate(B, R, Init);
1983 return setImplicitDefaultValue(B, R, ElementTy);
1989 RegionBindingsRef NewB(B);
1991 for (; Size.hasValue() ? i < Size.getValue() :
true ; ++i, ++VI) {
1996 const NonLoc &Idx = svalBuilder.makeArrayIndex(i);
1997 const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx);
2000 NewB = bindStruct(NewB, ER, *VI);
2002 NewB = bindArray(NewB, ER, *VI);
2009 if (Size.hasValue() && i < Size.getValue())
2010 NewB = setImplicitDefaultValue(NewB, R, ElementTy);
2024 return bindAggregate(B, R, V);
2033 QualType ElemType = VT->getElementType();
2036 unsigned index = 0, numElements = VT->getNumElements();
2037 RegionBindingsRef NewB(B);
2039 for ( ; index != numElements ; ++index) {
2043 NonLoc Idx = svalBuilder.makeArrayIndex(index);
2044 const ElementRegion *ER = MRMgr.getElementRegion(ElemType, Idx, R, Ctx);
2047 NewB = bindArray(NewB, ER, *VI);
2049 NewB = bindStruct(NewB, ER, *VI);
2063 if (
const CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(RD))
2064 if (Class->getNumBases() != 0 || Class->getNumVBases() != 0)
2067 for (
const auto *FD : RD->
fields()) {
2068 if (FD->isUnnamedBitfield())
2073 if (Fields.size() == SmallStructLimit)
2080 Fields.push_back(FD);
2083 RegionBindingsRef NewB = B;
2085 for (FieldVector::iterator I = Fields.begin(), E = Fields.end(); I != E; ++I){
2087 SVal V = getBindingForField(getRegionBindings(LCV.
getStore()), SourceFR);
2089 const FieldRegion *DestFR = MRMgr.getFieldRegion(*I, R);
2099 if (!Features.supportsFields())
2108 if (!RD->isCompleteDefinition())
2116 return bindAggregate(B, R, V);
2119 return bindAggregate(B, R, V);
2131 RegionBindingsRef NewB(B);
2133 for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI) {
2139 if (FI->isUnnamedBitfield())
2143 const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
2146 NewB = bindArray(NewB, FR, *VI);
2148 NewB = bindStruct(NewB, FR, *VI);
2156 NewB = NewB.addBinding(R, BindingKey::Default,
2157 svalBuilder.makeIntVal(0,
false));
2169 return removeSubRegionBindings(B, R).addBinding(R, BindingKey::Default, Val);
2177 class removeDeadBindingsWorker :
2178 public ClusterAnalysis<removeDeadBindingsWorker> {
2184 removeDeadBindingsWorker(RegionStoreManager &rm,
2188 : ClusterAnalysis<removeDeadBindingsWorker>(rm, stateMgr, b, GFK_None),
2189 SymReaper(symReaper), CurrentLCtx(LCtx) {}
2194 using ClusterAnalysis<removeDeadBindingsWorker>::VisitCluster;
2196 bool UpdatePostponed();
2197 void VisitBinding(
SVal V);
2201 void removeDeadBindingsWorker::VisitAddedToCluster(
const MemRegion *baseR,
2204 if (
const VarRegion *VR = dyn_cast<VarRegion>(baseR)) {
2205 if (SymReaper.isLive(VR))
2206 AddToWorkList(baseR, &C);
2211 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
2212 if (SymReaper.isLive(SR->getSymbol()))
2213 AddToWorkList(SR, &C);
2215 Postponed.push_back(SR);
2220 if (isa<NonStaticGlobalSpaceRegion>(baseR)) {
2221 AddToWorkList(baseR, &C);
2226 if (
const CXXThisRegion *TR = dyn_cast<CXXThisRegion>(baseR)) {
2231 (RegCtx == CurrentLCtx || RegCtx->isParentOf(CurrentLCtx)))
2232 AddToWorkList(TR, &C);
2236 void removeDeadBindingsWorker::VisitCluster(
const MemRegion *baseR,
2243 if (
const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(baseR))
2244 SymReaper.markLive(SymR->getSymbol());
2246 for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E; ++I)
2247 VisitBinding(I.getData());
2250 void removeDeadBindingsWorker::VisitBinding(
SVal V) {
2255 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
2257 for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
2272 E = BR->referenced_vars_end();
2273 for ( ; I != E; ++I)
2282 SymReaper.markLive(*SI);
2285 bool removeDeadBindingsWorker::UpdatePostponed() {
2288 bool changed =
false;
2291 I = Postponed.begin(), E = Postponed.end() ; I != E ; ++I) {
2293 if (SymReaper.isLive(SR->getSymbol())) {
2294 changed |= AddToWorkList(SR);
2303 StoreRef RegionStoreManager::removeDeadBindings(
Store store,
2306 RegionBindingsRef B = getRegionBindings(store);
2307 removeDeadBindingsWorker W(*
this, StateMgr, B, SymReaper, LCtx);
2308 W.GenerateClusters();
2313 W.AddToWorkList(*I);
2316 do W.RunWorkList();
while (W.UpdatePostponed());
2321 for (RegionBindingsRef::iterator I = B.begin(), E = B.end(); I != E; ++I) {
2325 if (W.isVisited(Base))
2336 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
2338 SVal X = CI.getData();
2340 for (; SI != SE; ++SI)
2345 return StoreRef(B.asStore(), *
this);
2352 void RegionStoreManager::print(
Store store, raw_ostream &OS,
2353 const char* nl,
const char *sep) {
2354 RegionBindingsRef B = getRegionBindings(store);
2355 OS <<
"Store (direct and default bindings), "
TypedValueRegion - An abstract class representing regions having a typed value.
MemRegion - The root abstract class for all memory regions.
virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const
getExtent - Returns the size of the region in bytes.
bool isInSystemHeader() const
Returns true if the callee is known to be from a system header.
static void getSymbolicOffsetFields(BindingKey K, FieldVector &Fields)
bool operator==(CanQual< T > x, CanQual< U > y)
Information about invalidation for a particular region/symbol.
bool maybeDead(SymbolRef sym)
If a symbol is known to be live, marks the symbol as live.
virtual QualType getValueType() const =0
virtual bool isBoundable() const
static bool isRecordEmpty(const RecordDecl *RD)
bool isVoidPointerType() const
const Expr * getInit() const
static Optional< nonloc::LazyCompoundVal > getExistingLazyBinding(SValBuilder &SVB, RegionBindingsConstRef B, const SubRegion *R, bool AllowSubregionBindings)
Value representing integer constant.
QualType getElementType() const
const MemRegion * getBaseRegion() const
bool isZeroConstant() const
std::unique_ptr< StoreManager > CreateFieldsOnlyRegionStoreManager(ProgramStateManager &StMgr)
Symbolic value. These values used to capture symbolic execution of the program.
llvm::ImmutableMap< BindingKey, SVal > ClusterBindings
const MemSpaceRegion * getMemorySpace() const
bool isScalarType() const
SmallVector< const FieldDecl *, 8 > FieldVector
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ASTMatchFinder::BindKind Bind
bool isReferenceType() const
bool isStructureOrClassType() const
bool isAnyPointerType() const
const MemRegion * getRegion() const
static bool canSymbolicate(QualType T)
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const VarDecl * getDecl() const
RegionRawOffset getAsArrayOffset() const
Compute the offset within the array. The array might also be a subobject.
static bool isLocType(QualType T)
uint32_t getCodeUnit(size_t i) const
unsigned getLength() const
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
field_range fields() const
SymbolRef getSymbol() const
bool isUnknownOrUndef() const
llvm::ImmutableMap< const MemRegion *, ClusterBindings > RegionBindings
SymExpr::symbol_iterator symbol_begin() const
QualType getValueType() const override
Represent a region's offset within the top level base region.
virtual QualType getType() const =0
const MemRegion * getSuperRegion() const
std::unique_ptr< StoreManager > CreateRegionStoreManager(ProgramStateManager &StMgr)
const StackFrameContext * getStackFrame() const
llvm::ImmutableList< SVal >::iterator iterator
static bool isCompatibleWithFields(BindingKey K, const FieldVector &Fields)
ID
Defines the set of possible language-specific address spaces.
QualType getPointeeType() const
static void collectSubRegionBindings(SmallVectorImpl< BindingPair > &Bindings, SValBuilder &SVB, const ClusterBindings &Cluster, const SubRegion *Top, BindingKey TopKey, bool IncludeAllDefaultBindings)
const VarRegion * getCapturedRegion() const
bool hasSymbolicOffset() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
RegionSetTy::const_iterator region_iterator
The result type of a method or function.
RecordDecl * getDefinition() const
const LazyCompoundValData * getCVData() const
llvm::ImmutableMapRef< BindingKey, SVal > ClusterBindingsRef
const MatchFinder::MatchFinderOptions & Options
bool scan(nonloc::LazyCompoundVal val)
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
region_iterator region_begin() const
static QualType getUnderlyingType(const SubRegion *R)
const FieldDecl * getDecl() const
bool isSubRegionOf(const MemRegion *R) const override
Check if the region is a subregion of the given region.
ASTContext & getContext()
SymExpr::symbol_iterator symbol_end() const
A class responsible for cleaning up unused symbols.
QualType getLocationType() const override
bool isVectorType() const
bool operator<(DeclarationName LHS, DeclarationName RHS)
Tells that a region's contents is not changed.
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
static const Type * getElementType(const Expr *BaseExpr)
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.
Represents symbolic expression.
const MemRegion * getAsRegion() const
Represents an abstract call to a function or method along a particular path.
region_iterator region_end() const
int64_t getOffset() const
const TypedValueRegion * getRegion() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
std::pair< BindingKey, SVal > BindingPair
__PTRDIFF_TYPE__ ptrdiff_t
static bool isUnionField(const FieldRegion *FR)
Represents a C++ struct/union/class.
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef. Otherwise, return 0.
Defines the clang::TargetInfo interface.
StringRegion - Region associated with a StringLiteral.
ElementRegin is used to represent both array elements and casts.
QualType getValueType() const override
const MemRegion * getRegion() const
virtual bool isSubRegionOf(const MemRegion *R) const
Check if the region is a subregion of the given region.
QualType getElementType() const
int getOptionAsInteger(StringRef Name, int DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
const RegionBindingsRef & RegionBindingsConstRef
bool hasStackNonParametersStorage() const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
TypedRegion - An abstract class representing regions that are typed.
bool hasLocalStorage() const
const RecordDecl * getParent() const
Iterator over symbols that the current symbol depends on.
const void * getStore() const