29 #include "llvm/ADT/ImmutableList.h"
30 #include "llvm/ADT/ImmutableMap.h"
31 #include "llvm/ADT/Optional.h"
32 #include "llvm/Support/raw_ostream.h"
35 using namespace clang;
45 enum Kind { Default = 0x0, Direct = 0x1 };
47 enum { Symbolic = 0x2 };
49 llvm::PointerIntPair<const MemRegion *, 2>
P;
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)) &&
"Not a base");
69 bool isDirect()
const {
return P.getInt() & Direct; }
70 bool hasSymbolicOffset()
const {
return P.getInt() & Symbolic; }
72 const MemRegion *getRegion()
const {
return P.getPointer(); }
73 uint64_t getOffset()
const {
74 assert(!hasSymbolicOffset());
78 const SubRegion *getConcreteOffsetRegion()
const {
79 assert(hasSymbolicOffset());
84 if (hasSymbolicOffset())
89 void Profile(llvm::FoldingSetNodeID&
ID)
const {
90 ID.AddPointer(
P.getOpaqueValue());
97 if (
P.getOpaqueValue() < X.P.getOpaqueValue())
99 if (
P.getOpaqueValue() > X.P.getOpaqueValue())
101 return Data < X.Data;
105 return P.getOpaqueValue() == X.P.getOpaqueValue() &&
116 return BindingKey(cast<SubRegion>(R), cast<SubRegion>(RO.
getRegion()), k);
124 os <<
'(' << K.getRegion();
125 if (!K.hasSymbolicOffset())
126 os <<
',' << K.getOffset();
127 os <<
',' << (K.isDirect() ?
"direct" :
"default")
132 template <
typename T>
struct isPodLike;
134 static const bool value =
true;
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).
196 removeBinding(R, BindingKey::Default);
206 Store asStore()
const {
207 return asImmutableMap().getRootWithoutRetain();
210 void dump(raw_ostream &OS,
const char *nl)
const {
215 OS <<
' ' << CI.getKey() <<
" : " << CI.getData() << nl;
221 LLVM_DUMP_METHOD
void dump()
const {
dump(llvm::errs(),
"\n"); }
234 if (TR->getValueType()->isUnionType())
240 RegionBindingsRef RegionBindingsRef::addBinding(BindingKey K,
SVal V)
const {
241 const MemRegion *Base = K.getBaseRegion();
245 (ExistingCluster ? *ExistingCluster : CBFactory->getEmptyMap());
248 return add(Base, NewCluster);
252 RegionBindingsRef RegionBindingsRef::addBinding(
const MemRegion *R,
258 const SVal *RegionBindingsRef::lookup(BindingKey K)
const {
262 return Cluster->lookup(K);
266 BindingKey::Kind k)
const {
270 RegionBindingsRef RegionBindingsRef::removeBinding(BindingKey K) {
271 const MemRegion *Base = K.getBaseRegion();
277 if (NewCluster.isEmpty())
279 return add(Base, NewCluster);
282 RegionBindingsRef RegionBindingsRef::removeBinding(
const MemRegion *R,
292 struct minimal_features_tag {};
293 struct maximal_features_tag {};
295 class RegionStoreFeatures {
298 RegionStoreFeatures(minimal_features_tag) :
299 SupportsFields(
false) {}
301 RegionStoreFeatures(maximal_features_tag) :
302 SupportsFields(
true) {}
304 void enableFields(
bool t) { SupportsFields = t; }
306 bool supportsFields()
const {
return SupportsFields; }
315 class invalidateRegionsWorker;
319 const RegionStoreFeatures Features;
321 RegionBindings::Factory RBFactory;
322 mutable ClusterBindings::Factory CBFactory;
324 typedef std::vector<SVal> SValListTy;
327 SValListTy> LazyBindingsMapTy;
328 LazyBindingsMapTy LazyBindingsMap;
338 unsigned SmallStructLimit;
342 void populateWorkList(invalidateRegionsWorker &W,
344 InvalidatedRegions *TopLevelRegions);
349 RBFactory(mgr.getAllocator()), CBFactory(mgr.getAllocator()),
350 SmallStructLimit(0) {
351 if (
SubEngine *Eng = StateMgr.getOwningEngine()) {
374 return StoreRef(RBFactory.getEmptyMap().getRootWithoutRetain(), *
this);
385 InvalidatedRegions *Invalidated);
394 InvalidatedRegions *Invalidated,
395 InvalidatedRegions *InvalidatedTopLevel)
override;
406 return StoreRef(bind(getRegionBindings(store), LV, V).asStore(), *
this);
413 RegionBindingsRef B = getRegionBindings(store);
414 assert(!B.lookup(R, BindingKey::Direct));
418 const SubRegion *SR = cast<SubRegion>(R);
421 "A default value must come from a super-region");
422 B = removeSubRegionBindings(B, SR);
424 B = B.addBinding(Key, V);
427 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *
this);
468 void incrementReferenceCount(
Store store)
override {
469 getRegionBindings(store).manualRetain();
475 void decrementReferenceCount(
Store store)
override {
476 getRegionBindings(store).manualRelease();
479 bool includedInBindings(
Store store,
const MemRegion *region)
const override;
495 return getBinding(getRegionBindings(S), L, T);
515 RegionBindingsRef LazyBinding);
540 std::pair<Store, const SubRegion *>
574 RegionBindingsRef getRegionBindings(
Store store)
const {
575 return RegionBindingsRef(CBFactory,
576 static_cast<const RegionBindings::TreeTy*>(store),
577 RBFactory.getTreeFactory());
580 void print(
Store store, raw_ostream &Out,
const char* nl,
581 const char *sep)
override;
583 void iterBindings(
Store store, BindingsHandler& f)
override {
584 RegionBindingsRef B = getRegionBindings(store);
589 const BindingKey &K = CI.getKey();
592 if (
const SubRegion *R = dyn_cast<SubRegion>(K.getRegion())) {
594 if (!f.HandleBinding(*
this, store, R, CI.getData()))
608 std::unique_ptr<StoreManager>
610 RegionStoreFeatures F = maximal_features_tag();
611 return llvm::make_unique<RegionStoreManager>(StMgr, F);
614 std::unique_ptr<StoreManager>
616 RegionStoreFeatures F = minimal_features_tag();
617 F.enableFields(
true);
618 return llvm::make_unique<RegionStoreManager>(StMgr, F);
638 template <
typename DERIVED>
639 class ClusterAnalysis {
641 typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
642 typedef const MemRegion * WorkListElement;
645 llvm::SmallPtrSet<const ClusterBindings *, 16> Visited;
649 RegionStoreManager &RM;
664 bool includeEntireMemorySpace(
const MemRegion *Base) {
671 : RM(rm), Ctx(StateMgr.getContext()),
672 svalBuilder(StateMgr.getSValBuilder()), B(std::move(b)) {}
674 RegionBindingsRef getRegionBindings()
const {
return B; }
677 return Visited.count(getCluster(R));
680 void GenerateClusters() {
687 assert(!Cluster.isEmpty() &&
"Empty clusters should be removed");
688 static_cast<DERIVED*
>(
this)->VisitAddedToCluster(Base, Cluster);
692 if (static_cast<DERIVED*>(
this)->includeEntireMemorySpace(Base))
693 AddToWorkList(WorkListElement(Base), &Cluster);
698 if (C && !Visited.insert(C).second)
705 return static_cast<DERIVED*
>(
this)->AddToWorkList(R);
709 while (!WL.empty()) {
710 WorkListElement E = WL.pop_back_val();
713 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, getCluster(BaseR));
722 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, C);
731 bool RegionStoreManager::scanReachableSymbols(
Store S,
const MemRegion *R,
733 assert(R == R->
getBaseRegion() &&
"Should only be called for base regions");
734 RegionBindingsRef B = getRegionBindings(S);
742 if (!Callbacks.
scan(RI.getData()))
756 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
758 const MemRegion *Base = K.getConcreteOffsetRegion();
762 if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R))
764 Fields.push_back(FR->getDecl());
766 R = cast<SubRegion>(R)->getSuperRegion();
771 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
781 return std::equal(FieldsInBindingKey.begin() +
Delta,
782 FieldsInBindingKey.end(),
785 return std::equal(FieldsInBindingKey.begin(), FieldsInBindingKey.end(),
786 Fields.begin() -
Delta);
802 bool IncludeAllDefaultBindings) {
804 if (TopKey.hasSymbolicOffset()) {
806 Top = cast<SubRegion>(TopKey.getConcreteOffsetRegion());
811 uint64_t
Length = UINT64_MAX;
815 const llvm::APSInt &ExtentInt = ExtentCI->getValue();
816 assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned());
819 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(Top)) {
820 if (FR->getDecl()->isBitField())
821 Length = FR->getDecl()->getBitWidthValue(SVB.
getContext());
826 BindingKey NextKey =
I.getKey();
827 if (NextKey.getRegion() == TopKey.getRegion()) {
833 if (NextKey.getOffset() > TopKey.getOffset() &&
834 NextKey.getOffset() - TopKey.getOffset() <
Length) {
837 Bindings.push_back(*
I);
839 }
else if (NextKey.getOffset() == TopKey.getOffset()) {
846 if (IncludeAllDefaultBindings || NextKey.isDirect())
847 Bindings.push_back(*
I);
850 }
else if (NextKey.hasSymbolicOffset()) {
851 const MemRegion *Base = NextKey.getConcreteOffsetRegion();
856 if (IncludeAllDefaultBindings || NextKey.isDirect())
858 Bindings.push_back(*
I);
859 }
else if (
const SubRegion *BaseSR = dyn_cast<SubRegion>(Base)) {
864 Bindings.push_back(*
I);
873 const SubRegion *Top,
bool IncludeAllDefaultBindings) {
876 IncludeAllDefaultBindings);
883 const MemRegion *ClusterHead = TopKey.getBaseRegion();
885 if (Top == ClusterHead) {
887 return B.remove(Top);
894 if (TopKey.hasSymbolicOffset()) {
895 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
896 return B.addBinding(Concrete, BindingKey::Default,
UnknownVal());
909 Result =
Result.remove(
I->first);
915 if (TopKey.hasSymbolicOffset()) {
916 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
922 return B.remove(ClusterHead);
923 return B.add(ClusterHead,
Result.asImmutableMap());
927 class invalidateRegionsWorker :
public ClusterAnalysis<invalidateRegionsWorker>
937 invalidateRegionsWorker(RegionStoreManager &rm,
940 const Expr *ex,
unsigned count,
946 : ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b),
947 Ex(ex),
Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r),
948 GlobalsFilter(GFK) {}
951 void VisitBinding(
SVal V);
953 using ClusterAnalysis::AddToWorkList;
959 bool includeEntireMemorySpace(
const MemRegion *Base);
963 bool isInitiallyIncludedGlobalRegion(
const MemRegion *R);
967 bool invalidateRegionsWorker::AddToWorkList(
const MemRegion *R) {
968 bool doNotInvalidateSuperRegion = ITraits.hasTrait(
971 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
974 void invalidateRegionsWorker::VisitBinding(
SVal V) {
988 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
990 for (RegionStoreManager::SValListTy::const_iterator
I = Vals.begin(),
999 void invalidateRegionsWorker::VisitCluster(
const MemRegion *baseR,
1002 bool PreserveRegionsContents =
1003 ITraits.hasTrait(baseR,
1008 VisitBinding(
I.getData());
1011 if (!PreserveRegionsContents)
1012 B = B.remove(baseR);
1019 BI = BR->referenced_vars_begin(), BE = BR->referenced_vars_end() ;
1021 const VarRegion *VR = BI.getCapturedRegion();
1044 IS.insert(SR->getSymbol());
1047 if (PreserveRegionsContents)
1052 Regions->push_back(baseR);
1054 if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
1058 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx, Ctx.IntTy,
Count);
1059 B = B.addBinding(baseR, BindingKey::Default, V);
1069 if (isInitiallyIncludedGlobalRegion(baseR)) {
1076 if (T->isStructureOrClassType()) {
1081 B = B.addBinding(baseR, BindingKey::Default, V);
1085 if (
const ArrayType *AT = Ctx.getAsArrayType(T)) {
1086 bool doNotInvalidateSuperRegion = ITraits.hasTrait(
1090 if (doNotInvalidateSuperRegion) {
1097 NumElements = CAT->getSize().getZExtValue();
1099 goto conjure_default;
1100 QualType ElementTy = AT->getElementType();
1101 uint64_t ElemSize = Ctx.getTypeSize(ElementTy);
1108 AddToWorkList(SuperR);
1109 goto conjure_default;
1113 uint64_t UpperOffset = LowerOffset + *NumElements * ElemSize;
1114 bool UpperOverflow = UpperOffset < LowerOffset;
1119 goto conjure_default;
1123 goto conjure_default;
1127 const BindingKey &BK =
I.getKey();
1134 ((*ROffset >= LowerOffset && *ROffset < UpperOffset) ||
1136 (*ROffset >= LowerOffset || *ROffset < UpperOffset)) ||
1137 (LowerOffset == UpperOffset && *ROffset == LowerOffset))) {
1138 B = B.removeBinding(
I.getKey());
1141 SVal V =
I.getData();
1143 if (R && isa<SymbolicRegion>(R))
1151 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
1152 AT->getElementType(),
Count);
1153 B = B.addBinding(baseR, BindingKey::Default, V);
1160 B = B.addBinding(baseR, BindingKey::Direct, V);
1163 bool invalidateRegionsWorker::isInitiallyIncludedGlobalRegion(
1165 switch (GlobalsFilter) {
1168 case GFK_SystemOnly:
1174 llvm_unreachable(
"unknown globals filter");
1177 bool invalidateRegionsWorker::includeEntireMemorySpace(
const MemRegion *Base) {
1178 if (isInitiallyIncludedGlobalRegion(Base))
1182 return ITraits.hasTrait(MemSpace,
1191 RegionBindingsRef B,
1192 InvalidatedRegions *Invalidated) {
1196 SVal V = svalBuilder.conjureSymbolVal( (
const void*) GS, Ex, LCtx,
1200 B = B.removeBinding(GS)
1206 Invalidated->push_back(GS);
1211 void RegionStoreManager::populateWorkList(invalidateRegionsWorker &W,
1213 InvalidatedRegions *TopLevelRegions) {
1215 E = Values.end();
I !=
E; ++
I) {
1220 const SValListTy &Vals = getInterestingValues(*LCS);
1222 for (SValListTy::const_iterator
I = Vals.begin(),
1223 E = Vals.end();
I !=
E; ++
I) {
1226 if (
const MemRegion *R = (*I).getAsRegion())
1233 if (TopLevelRegions)
1234 TopLevelRegions->push_back(R);
1242 RegionStoreManager::invalidateRegions(
Store store,
1244 const Expr *Ex,
unsigned Count,
1249 InvalidatedRegions *TopLevelRegions,
1250 InvalidatedRegions *Invalidated) {
1254 GlobalsFilter = GFK_SystemOnly;
1256 GlobalsFilter = GFK_All;
1258 GlobalsFilter = GFK_None;
1261 RegionBindingsRef B = getRegionBindings(store);
1262 invalidateRegionsWorker W(*
this, StateMgr, B, Ex, Count, LCtx, IS, ITraits,
1263 Invalidated, GlobalsFilter);
1266 W.GenerateClusters();
1269 populateWorkList(W, Values, TopLevelRegions);
1274 B = W.getRegionBindings();
1280 switch (GlobalsFilter) {
1282 B = invalidateGlobalRegion(MemRegion::GlobalInternalSpaceRegionKind,
1283 Ex, Count, LCtx, B, Invalidated);
1285 case GFK_SystemOnly:
1286 B = invalidateGlobalRegion(MemRegion::GlobalSystemSpaceRegionKind,
1287 Ex, Count, LCtx, B, Invalidated);
1293 return StoreRef(B.asStore(), *
this);
1304 SVal Size = cast<SubRegion>(R)->getExtent(svalBuilder);
1305 const llvm::APSInt *SizeInt = svalBuilder.getKnownValue(state, Size);
1311 if (Ctx.getAsVariableArrayType(EleTy)) {
1318 CharUnits EleSize = Ctx.getTypeSizeInChars(EleTy);
1323 return svalBuilder.makeIntVal(RegionSize / EleSize,
false);
1341 NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex();
1368 if (isa<BlockDataRegion>(MR)) {
1372 if (isa<AllocaRegion>(MR) ||
1373 isa<SymbolicRegion>(MR) ||
1374 isa<CodeTextRegion>(MR)) {
1376 if (
const TypedRegion *TR = dyn_cast<TypedRegion>(MR))
1383 MR = GetElementZeroRegion(MR, T);
1393 if (RTy->isAnyComplexType())
1404 if (RTy->isStructureOrClassType())
1405 return getBindingForStruct(B, R);
1408 if (RTy->isUnionType())
1409 return createLazyBinding(B, R);
1411 if (RTy->isArrayType()) {
1412 if (RTy->isConstantArrayType())
1413 return getBindingForArray(B, R);
1419 if (RTy->isVectorType())
1422 if (
const FieldRegion* FR = dyn_cast<FieldRegion>(R))
1423 return CastRetrievedVal(getBindingForField(B, FR), FR, T,
false);
1431 return CastRetrievedVal(getBindingForElement(B, ER), ER, T,
false);
1441 return CastRetrievedVal(getBindingForObjCIvar(B, IVR), IVR, T,
false);
1444 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
1451 return CastRetrievedVal(getBindingForVar(B, VR), VR, T,
false);
1454 const SVal *V = B.lookup(R, BindingKey::Direct);
1472 return svalBuilder.getRegionValueSymbolVal(R);
1478 RegionTy = TVR->getValueType();
1481 RegionTy = SR->getSymbol()->getType();
1495 const SubRegion *R,
bool AllowSubregionBindings) {
1507 if (!RegionTy.
isNull() &&
1509 QualType SourceRegionTy = LCV->getRegion()->getValueType();
1514 if (!AllowSubregionBindings) {
1520 if (Bindings.size() > 1)
1528 std::pair<Store, const SubRegion *>
1532 if (originalRegion != R) {
1535 return std::make_pair(V->getStore(), V->getRegion());
1538 typedef std::pair<Store, const SubRegion *> StoreRegionPair;
1539 StoreRegionPair
Result = StoreRegionPair();
1542 Result = findLazyBinding(B, cast<SubRegion>(ER->getSuperRegion()),
1546 Result.second = MRMgr.getElementRegionWithSuper(ER, Result.second);
1548 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
1549 Result = findLazyBinding(B, cast<SubRegion>(FR->getSuperRegion()),
1553 Result.second = MRMgr.getFieldRegionWithSuper(FR, Result.second);
1556 dyn_cast<CXXBaseObjectRegion>(R)) {
1559 Result = findLazyBinding(B, cast<SubRegion>(BaseReg->getSuperRegion()),
1563 Result.second = MRMgr.getCXXBaseObjectRegionWithSuper(BaseReg,
1583 if (
const StringRegion *StrR=dyn_cast<StringRegion>(superR)) {
1586 QualType T = Ctx.getAsArrayType(StrR->getValueType())->getElementType();
1593 int64_t i = CI->getValue().getSExtValue();
1604 return svalBuilder.makeIntVal(c, T);
1609 if (isa<CodeTextRegion>(superR))
1625 dyn_cast_or_null<TypedValueRegion>(O.
getRegion())) {
1626 QualType baseT = baseR->getValueType();
1630 if (Ctx.getTypeSizeInChars(baseT) >= Ctx.getTypeSizeInChars(elemT)) {
1633 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1645 return getBindingForFieldOrElementCommon(B, R, R->
getElementType());
1656 return getBindingForFieldOrElementCommon(B, R, Ty);
1666 const SVal &val = D.getValue();
1668 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1671 return svalBuilder.makeZeroVal(Ty);
1681 llvm_unreachable(
"Unknown default value");
1687 SVal RegionStoreManager::getLazyBinding(
const SubRegion *LazyBindingRegion,
1688 RegionBindingsRef LazyBinding) {
1690 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(LazyBindingRegion))
1691 Result = getBindingForElement(LazyBinding, ER);
1693 Result = getBindingForField(LazyBinding,
1694 cast<FieldRegion>(LazyBindingRegion));
1725 Store lazyBindingStore =
nullptr;
1726 const SubRegion *lazyBindingRegion =
nullptr;
1727 std::tie(lazyBindingStore, lazyBindingRegion) = findLazyBinding(B, R, R);
1728 if (lazyBindingRegion)
1729 return getLazyBinding(lazyBindingRegion,
1730 getRegionBindings(lazyBindingStore));
1734 bool hasSymbolicIndex =
false;
1750 bool hasPartialLazyBinding =
false;
1755 if (
Optional<SVal> D = getBindingForDerivedDefaultValue(B, Base, R, Ty)) {
1757 hasPartialLazyBinding =
true;
1764 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(Base)) {
1765 NonLoc index = ER->getIndex();
1767 hasSymbolicIndex =
true;
1776 if (isa<ElementRegion>(R)) {
1781 if (typedSuperR->getValueType()->isVectorType())
1790 if (hasSymbolicIndex)
1793 if (!hasPartialLazyBinding)
1798 return svalBuilder.getRegionValueSymbolVal(R);
1812 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1818 return getBindingForLazySymbol(R);
1833 if (isa<StackArgumentsSpaceRegion>(MS))
1834 return svalBuilder.getRegionValueSymbolVal(R);
1844 if (isa<UnknownSpaceRegion>(MS))
1845 return svalBuilder.getRegionValueSymbolVal(R);
1847 if (isa<GlobalsSpaceRegion>(MS)) {
1852 if (isa<StaticGlobalSpaceRegion>(MS))
1853 return svalBuilder.makeZeroVal(T);
1855 if (
Optional<SVal> V = getBindingForDerivedDefaultValue(B, MS, R, T)) {
1857 return V.getValue();
1860 return svalBuilder.getRegionValueSymbolVal(R);
1868 return svalBuilder.getRegionValueSymbolVal(R);
1871 const RegionStoreManager::SValListTy &
1875 if (I != LazyBindingsMap.end())
1882 RegionBindingsRef B = getRegionBindings(LCV.
getStore());
1888 return (LazyBindingsMap[LCV.
getCVData()] = std::move(List));
1902 const SValListTy &InnerList = getInterestingValues(*InnerLCV);
1903 List.insert(List.end(), InnerList.begin(), InnerList.end());
1910 return (LazyBindingsMap[LCV.
getCVData()] = std::move(List));
1919 return svalBuilder.makeLazyCompoundVal(
StoreRef(B.asStore(), *
this), R);
1926 return CRD->getNumBases() == 0;
1936 return createLazyBinding(B, R);
1941 assert(Ctx.getAsConstantArrayType(R->
getValueType()) &&
1942 "Only constant array types can have compound bindings.");
1944 return createLazyBinding(B, R);
1947 bool RegionStoreManager::includedInBindings(
Store store,
1949 RegionBindingsRef B = getRegionBindings(store);
1953 if (B.lookup(region))
1961 const SVal &D = CI.getData();
1977 if (
const MemRegion* R = LV->getRegion())
1978 return StoreRef(getRegionBindings(ST).removeBinding(R)
1980 .getRootWithoutRetain(),
1998 return bindArray(B, TR, V);
2000 return bindStruct(B, TR, V);
2002 return bindVector(B, TR, V);
2004 return bindAggregate(B, TR, V);
2010 QualType T = SR->getSymbol()->getType();
2014 R = GetElementZeroRegion(SR, T);
2018 RegionBindingsRef NewB = removeSubRegionBindings(B, cast<SubRegion>(R));
2029 V = svalBuilder.makeNull();
2031 V = svalBuilder.makeZeroVal(T);
2035 V = svalBuilder.makeZeroVal(Ctx.IntTy);
2046 return B.addBinding(R, BindingKey::Default, V);
2059 Size = CAT->getSize().getZExtValue();
2063 const StringRegion *S = cast<StringRegion>(MRV->getRegion());
2066 StoreRef store(B.asStore(), *
this);
2069 return bindAggregate(B, R, LCV);
2074 return bindAggregate(B, R, Init);
2079 return setImplicitDefaultValue(B, R, ElementTy);
2085 RegionBindingsRef NewB(B);
2087 for (; Size.hasValue() ? i < Size.getValue() :
true ; ++i, ++VI) {
2092 const NonLoc &Idx = svalBuilder.makeArrayIndex(i);
2093 const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx);
2096 NewB = bindStruct(NewB, ER, *VI);
2098 NewB = bindArray(NewB, ER, *VI);
2105 if (Size.hasValue() && i < Size.getValue())
2106 NewB = setImplicitDefaultValue(NewB, R, ElementTy);
2120 return bindAggregate(B, R, V);
2129 QualType ElemType = VT->getElementType();
2132 unsigned index = 0, numElements = VT->getNumElements();
2133 RegionBindingsRef NewB(B);
2135 for ( ; index != numElements ; ++index) {
2139 NonLoc Idx = svalBuilder.makeArrayIndex(index);
2140 const ElementRegion *ER = MRMgr.getElementRegion(ElemType, Idx, R, Ctx);
2143 NewB = bindArray(NewB, ER, *VI);
2145 NewB = bindStruct(NewB, ER, *VI);
2159 if (
const CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(RD))
2160 if (
Class->getNumBases() != 0 ||
Class->getNumVBases() != 0)
2163 for (
const auto *FD : RD->
fields()) {
2164 if (FD->isUnnamedBitfield())
2169 if (Fields.size() == SmallStructLimit)
2176 Fields.push_back(FD);
2179 RegionBindingsRef NewB = B;
2183 SVal V = getBindingForField(getRegionBindings(LCV.
getStore()), SourceFR);
2185 const FieldRegion *DestFR = MRMgr.getFieldRegion(*I, R);
2195 if (!Features.supportsFields())
2204 if (!RD->isCompleteDefinition())
2212 return bindAggregate(B, R, V);
2215 return bindAggregate(B, R, V);
2227 RegionBindingsRef NewB(B);
2229 for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI) {
2235 if (FI->isUnnamedBitfield())
2239 const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
2242 NewB = bindArray(NewB, FR, *VI);
2244 NewB = bindStruct(NewB, FR, *VI);
2252 NewB = NewB.addBinding(R, BindingKey::Default,
2253 svalBuilder.makeIntVal(0,
false));
2265 return removeSubRegionBindings(B, R).addBinding(R, BindingKey::Default, Val);
2273 class removeDeadBindingsWorker :
2274 public ClusterAnalysis<removeDeadBindingsWorker> {
2280 removeDeadBindingsWorker(RegionStoreManager &rm,
2284 : ClusterAnalysis<removeDeadBindingsWorker>(rm, stateMgr, b),
2285 SymReaper(symReaper), CurrentLCtx(LCtx) {}
2290 using ClusterAnalysis<removeDeadBindingsWorker>::VisitCluster;
2292 using ClusterAnalysis::AddToWorkList;
2296 bool UpdatePostponed();
2297 void VisitBinding(
SVal V);
2301 bool removeDeadBindingsWorker::AddToWorkList(
const MemRegion *R) {
2303 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
2306 void removeDeadBindingsWorker::VisitAddedToCluster(
const MemRegion *baseR,
2309 if (
const VarRegion *VR = dyn_cast<VarRegion>(baseR)) {
2310 if (SymReaper.isLive(VR))
2311 AddToWorkList(baseR, &C);
2316 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
2317 if (SymReaper.isLive(SR->getSymbol()))
2318 AddToWorkList(SR, &C);
2320 Postponed.push_back(SR);
2325 if (isa<NonStaticGlobalSpaceRegion>(baseR)) {
2326 AddToWorkList(baseR, &C);
2331 if (
const CXXThisRegion *TR = dyn_cast<CXXThisRegion>(baseR)) {
2336 (RegCtx == CurrentLCtx || RegCtx->isParentOf(CurrentLCtx)))
2337 AddToWorkList(TR, &C);
2341 void removeDeadBindingsWorker::VisitCluster(
const MemRegion *baseR,
2348 if (
const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(baseR))
2349 SymReaper.markLive(SymR->getSymbol());
2353 SymReaper.markElementIndicesLive(I.getKey().getRegion());
2355 VisitBinding(I.getData());
2359 void removeDeadBindingsWorker::VisitBinding(
SVal V) {
2364 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
2366 for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
2377 SymReaper.markLive(R);
2382 E = BR->referenced_vars_end();
2383 for ( ; I !=
E; ++
I)
2392 SymReaper.markLive(*SI);
2395 bool removeDeadBindingsWorker::UpdatePostponed() {
2398 bool changed =
false;
2401 I = Postponed.begin(), E = Postponed.end() ; I !=
E ; ++
I) {
2403 if (SymReaper.isLive(SR->getSymbol())) {
2404 changed |= AddToWorkList(SR);
2413 StoreRef RegionStoreManager::removeDeadBindings(
Store store,
2416 RegionBindingsRef B = getRegionBindings(store);
2417 removeDeadBindingsWorker W(*
this, StateMgr, B, SymReaper, LCtx);
2418 W.GenerateClusters();
2423 W.AddToWorkList(*I);
2426 do W.RunWorkList();
while (W.UpdatePostponed());
2435 if (W.isVisited(Base))
2448 SVal X = CI.getData();
2450 for (; SI != SE; ++SI)
2455 return StoreRef(B.asStore(), *
this);
2462 void RegionStoreManager::print(
Store store, raw_ostream &OS,
2463 const char* nl,
const char *sep) {
2464 RegionBindingsRef B = getRegionBindings(store);
2465 OS <<
"Store (direct and default bindings), "
TypedValueRegion - An abstract class representing regions having a typed value.
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
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 void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const Expr * getInit() const
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
static Optional< nonloc::LazyCompoundVal > getExistingLazyBinding(SValBuilder &SVB, RegionBindingsConstRef B, const SubRegion *R, bool AllowSubregionBindings)
Checks to see if store B has a lazy binding for region R.
Value representing integer constant.
A Utility class that allows to visit the reachable symbols using a custom SymbolVisitor.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
QualType getElementType() const
const MemRegion * getBaseRegion() const
bool isZeroConstant() const
std::unique_ptr< StoreManager > CreateFieldsOnlyRegionStoreManager(ProgramStateManager &StMgr)
CXXThisRegion - Represents the region for the implicit 'this' parameter in a call to a C++ method...
RecordDecl - Represents a struct/union/class.
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)
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 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
BlockDataRegion - A region that represents a block instance.
unsigned getLength() const
CharUnits - This is an opaque type for sizes expressed in character units.
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
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
detail::InMemoryDirectory::const_iterator I
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)
When applied to a MemSpaceRegion, indicates the entire memory space should be invalidated.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
SymbolicRegion - A special, "non-concrete" region.
static void collectSubRegionBindings(SmallVectorImpl< BindingPair > &Bindings, SValBuilder &SVB, const ClusterBindings &Cluster, const SubRegion *Top, BindingKey TopKey, bool IncludeAllDefaultBindings)
Collects all bindings in Cluster that may refer to bindings within Top.
Expr - This represents one expression.
GlobalsFilterKind
Used to determine which global regions are automatically included in the initial worklist of a Cluste...
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.
Represents a GCC generic vector type.
RegionSetTy::const_iterator region_iterator
The result type of a method or function.
float __ovld __cnfn length(float p)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
RecordDecl * getDefinition() const
getDefinition - Returns the RecordDecl that actually defines this struct/union/class.
const LazyCompoundValData * getCVData() const
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
llvm::ImmutableMapRef< BindingKey, SVal > ClusterBindingsRef
const MatchFinder::MatchFinderOptions & Options
bool scan(nonloc::LazyCompoundVal val)
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
const TemplateArgument * iterator
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
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
A class responsible for cleaning up unused symbols.
const T * castAs() const
Member-template castAs<specific type>.
QualType getLocationType() const override
bool isVectorType() const
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
Tells that a region's contents is not changed.
__PTRDIFF_TYPE__ ptrdiff_t
A signed integer type that is the result of subtracting two pointers.
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
Represents a template argument.
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.
detail::InMemoryDirectory::const_iterator E
const MemRegion * getAsRegion() const
Represents an abstract call to a function or method along a particular path.
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...
region_iterator region_end() const
const T * getAs() const
Member-template getAs<specific type>'.
SubRegion - A region that subsets another larger region.
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
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
static bool isUnionField(const FieldRegion *FR)
Represents a C++ struct/union/class.
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
StringLiteral - This represents a string literal expression, e.g.
Defines the clang::TargetInfo interface.
StringRegion - Region associated with a StringLiteral.
ElementRegin is used to represent both array elements and casts.
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)
Interprets an option's string value as an integer value.
const RegionBindingsRef & RegionBindingsConstRef
bool hasStackNonParametersStorage() const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isNull() const
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.
Represents the canonical version of C arrays with a specified constant size.
TypedRegion - An abstract class representing regions that are typed.
bool hasLocalStorage() const
hasLocalStorage - Returns true if a variable with function scope is a non-static local variable...
const RecordDecl * getParent() const
getParent - Returns the parent of this field declaration, which is the struct in which this method is...
Iterator over symbols that the current symbol depends on.
const void * getStore() const