29 #include "llvm/ADT/ImmutableMap.h"
30 #include "llvm/ADT/Optional.h"
31 #include "llvm/Support/raw_ostream.h"
34 using namespace clang;
46 enum { Symbolic = 0x2 };
48 llvm::PointerIntPair<const MemRegion *, 2>
P;
54 :
P(r, k | Symbolic), Data(reinterpret_cast<
uintptr_t>(Base)) {
55 assert(r && Base &&
"Must have known regions.");
56 assert(getConcreteOffsetRegion() == Base &&
"Failed to store base region");
60 explicit BindingKey(
const MemRegion *r, uint64_t offset,
Kind k)
61 :
P(r, k), Data(offset) {
62 assert(r &&
"Must have known regions.");
63 assert(getOffset() == offset &&
"Failed to store offset");
64 assert((r == r->
getBaseRegion() || isa<ObjCIvarRegion>(r)) &&
"Not a base");
68 bool isDirect()
const {
return P.getInt() & Direct; }
69 bool hasSymbolicOffset()
const {
return P.getInt() & Symbolic; }
71 const MemRegion *getRegion()
const {
return P.getPointer(); }
72 uint64_t getOffset()
const {
73 assert(!hasSymbolicOffset());
77 const SubRegion *getConcreteOffsetRegion()
const {
78 assert(hasSymbolicOffset());
83 if (hasSymbolicOffset())
88 void Profile(llvm::FoldingSetNodeID&
ID)
const {
89 ID.AddPointer(
P.getOpaqueValue());
96 if (
P.getOpaqueValue() < X.P.getOpaqueValue())
98 if (
P.getOpaqueValue() > X.P.getOpaqueValue())
100 return Data < X.Data;
104 return P.getOpaqueValue() == X.P.getOpaqueValue() &&
115 return BindingKey(cast<SubRegion>(R), cast<SubRegion>(RO.
getRegion()), k);
123 os <<
'(' << K.getRegion();
124 if (!K.hasSymbolicOffset())
125 os <<
',' << K.getOffset();
126 os <<
',' << (K.isDirect() ?
"direct" :
"default")
131 template <
typename T>
struct isPodLike;
133 static const bool value =
true;
151 class RegionBindingsRef :
public llvm::ImmutableMapRef<const MemRegion *,
153 ClusterBindings::Factory *CBFactory;
156 typedef llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>
159 RegionBindingsRef(ClusterBindings::Factory &CBFactory,
160 const RegionBindings::TreeTy *T,
161 RegionBindings::TreeTy::Factory *F)
162 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(T, F),
163 CBFactory(&CBFactory) {}
165 RegionBindingsRef(
const ParentTy &
P, ClusterBindings::Factory &CBFactory)
166 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(
P),
167 CBFactory(&CBFactory) {}
169 RegionBindingsRef add(key_type_ref K, data_type_ref D)
const {
170 return RegionBindingsRef(static_cast<const ParentTy *>(
this)->add(K, D),
174 RegionBindingsRef
remove(key_type_ref K)
const {
175 return RegionBindingsRef(static_cast<const ParentTy *>(
this)->
remove(K),
179 RegionBindingsRef addBinding(BindingKey K,
SVal V)
const;
181 RegionBindingsRef addBinding(
const MemRegion *R,
182 BindingKey::Kind k,
SVal V)
const;
184 const SVal *lookup(BindingKey K)
const;
185 const SVal *lookup(
const MemRegion *R, BindingKey::Kind k)
const;
186 using llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>::lookup;
188 RegionBindingsRef removeBinding(BindingKey K);
190 RegionBindingsRef removeBinding(
const MemRegion *R,
193 RegionBindingsRef removeBinding(
const MemRegion *R) {
194 return removeBinding(R, BindingKey::Direct).
198 Optional<SVal> getDirectBinding(
const MemRegion *R)
const;
202 Optional<SVal> getDefaultBinding(
const MemRegion *R)
const;
205 Store asStore()
const {
206 return asImmutableMap().getRootWithoutRetain();
209 void dump(raw_ostream &OS,
const char *nl)
const {
210 for (iterator
I = begin(),
E = end();
I !=
E; ++
I) {
212 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
214 OS <<
' ' << CI.getKey() <<
" : " << CI.getData() << nl;
220 LLVM_DUMP_METHOD
void dump()
const {
dump(llvm::errs(),
"\n"); }
226 Optional<SVal> RegionBindingsRef::getDirectBinding(
const MemRegion *R)
const {
230 Optional<SVal> RegionBindingsRef::getDefaultBinding(
const MemRegion *R)
const {
233 if (TR->getValueType()->isUnionType())
239 RegionBindingsRef RegionBindingsRef::addBinding(BindingKey K,
SVal V)
const {
240 const MemRegion *Base = K.getBaseRegion();
244 (ExistingCluster ? *ExistingCluster : CBFactory->getEmptyMap());
247 return add(Base, NewCluster);
251 RegionBindingsRef RegionBindingsRef::addBinding(
const MemRegion *R,
257 const SVal *RegionBindingsRef::lookup(BindingKey K)
const {
261 return Cluster->lookup(K);
265 BindingKey::Kind k)
const {
269 RegionBindingsRef RegionBindingsRef::removeBinding(BindingKey K) {
270 const MemRegion *Base = K.getBaseRegion();
276 if (NewCluster.isEmpty())
278 return add(Base, NewCluster);
281 RegionBindingsRef RegionBindingsRef::removeBinding(
const MemRegion *R,
291 struct minimal_features_tag {};
292 struct maximal_features_tag {};
294 class RegionStoreFeatures {
297 RegionStoreFeatures(minimal_features_tag) :
298 SupportsFields(
false) {}
300 RegionStoreFeatures(maximal_features_tag) :
301 SupportsFields(
true) {}
303 void enableFields(
bool t) { SupportsFields = t; }
305 bool supportsFields()
const {
return SupportsFields; }
314 class invalidateRegionsWorker;
318 const RegionStoreFeatures Features;
320 RegionBindings::Factory RBFactory;
321 mutable ClusterBindings::Factory CBFactory;
323 typedef std::vector<SVal> SValListTy;
326 SValListTy> LazyBindingsMapTy;
327 LazyBindingsMapTy LazyBindingsMap;
337 unsigned SmallStructLimit;
341 void populateWorkList(invalidateRegionsWorker &W,
343 InvalidatedRegions *TopLevelRegions);
348 RBFactory(mgr.getAllocator()), CBFactory(mgr.getAllocator()),
349 SmallStructLimit(0) {
350 if (
SubEngine *Eng = StateMgr.getOwningEngine()) {
373 return StoreRef(RBFactory.getEmptyMap().getRootWithoutRetain(), *
this);
384 InvalidatedRegions *Invalidated);
388 const Expr *
E,
unsigned Count,
393 InvalidatedRegions *Invalidated,
394 InvalidatedRegions *InvalidatedTopLevel)
override;
405 return StoreRef(bind(getRegionBindings(store), LV, V).asStore(), *
this);
421 if (R->
getKind() == MemRegion::CXXBaseObjectRegionKind &&
422 cast<CXXBaseObjectRegion>(R)->getDecl()->isEmpty())
425 RegionBindingsRef B = getRegionBindings(store);
426 assert(!B.lookup(R, BindingKey::Direct));
430 const SubRegion *SR = cast<SubRegion>(R);
433 "A default value must come from a super-region");
434 B = removeSubRegionBindings(B, SR);
436 B = B.addBinding(Key, V);
439 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *
this);
480 void incrementReferenceCount(
Store store)
override {
481 getRegionBindings(store).manualRetain();
487 void decrementReferenceCount(
Store store)
override {
488 getRegionBindings(store).manualRelease();
491 bool includedInBindings(
Store store,
const MemRegion *region)
const override;
507 return getBinding(getRegionBindings(S), L, T);
510 Optional<SVal> getDefaultBinding(
Store S,
const MemRegion *R)
override {
511 RegionBindingsRef B = getRegionBindings(S);
535 RegionBindingsRef LazyBinding);
560 std::pair<Store, const SubRegion *>
594 RegionBindingsRef getRegionBindings(
Store store)
const {
595 return RegionBindingsRef(CBFactory,
596 static_cast<const RegionBindings::TreeTy*>(store),
597 RBFactory.getTreeFactory());
600 void print(
Store store, raw_ostream &Out,
const char* nl,
601 const char *sep)
override;
603 void iterBindings(
Store store, BindingsHandler& f)
override {
604 RegionBindingsRef B = getRegionBindings(store);
605 for (RegionBindingsRef::iterator
I = B.begin(),
E = B.end();
I !=
E; ++
I) {
607 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
609 const BindingKey &K = CI.getKey();
612 if (
const SubRegion *R = dyn_cast<SubRegion>(K.getRegion())) {
614 if (!f.HandleBinding(*
this, store, R, CI.getData()))
628 std::unique_ptr<StoreManager>
630 RegionStoreFeatures F = maximal_features_tag();
631 return llvm::make_unique<RegionStoreManager>(StMgr, F);
634 std::unique_ptr<StoreManager>
636 RegionStoreFeatures F = minimal_features_tag();
637 F.enableFields(
true);
638 return llvm::make_unique<RegionStoreManager>(StMgr, F);
658 template <
typename DERIVED>
659 class ClusterAnalysis {
661 typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
662 typedef const MemRegion * WorkListElement;
665 llvm::SmallPtrSet<const ClusterBindings *, 16> Visited;
669 RegionStoreManager &RM;
684 bool includeEntireMemorySpace(
const MemRegion *Base) {
691 : RM(rm), Ctx(StateMgr.getContext()),
692 svalBuilder(StateMgr.getSValBuilder()), B(std::move(b)) {}
694 RegionBindingsRef getRegionBindings()
const {
return B; }
697 return Visited.count(getCluster(R));
700 void GenerateClusters() {
702 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end();
707 assert(!Cluster.isEmpty() &&
"Empty clusters should be removed");
708 static_cast<DERIVED*
>(
this)->VisitAddedToCluster(Base, Cluster);
712 if (static_cast<DERIVED*>(
this)->includeEntireMemorySpace(Base))
713 AddToWorkList(WorkListElement(Base), &Cluster);
718 if (C && !Visited.insert(C).second)
725 return static_cast<DERIVED*
>(
this)->AddToWorkList(R);
729 while (!WL.empty()) {
730 WorkListElement E = WL.pop_back_val();
733 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, getCluster(BaseR));
742 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, C);
751 bool RegionStoreManager::scanReachableSymbols(
Store S,
const MemRegion *R,
753 assert(R == R->
getBaseRegion() &&
"Should only be called for base regions");
754 RegionBindingsRef B = getRegionBindings(S);
760 for (ClusterBindings::iterator RI = Cluster->begin(), RE = Cluster->end();
762 if (!Callbacks.
scan(RI.getData()))
776 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
778 const MemRegion *Base = K.getConcreteOffsetRegion();
782 if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R))
784 Fields.push_back(FR->getDecl());
786 R = cast<SubRegion>(R)->getSuperRegion();
791 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
801 return std::equal(FieldsInBindingKey.begin() +
Delta,
802 FieldsInBindingKey.end(),
805 return std::equal(FieldsInBindingKey.begin(), FieldsInBindingKey.end(),
806 Fields.begin() -
Delta);
822 bool IncludeAllDefaultBindings) {
824 if (TopKey.hasSymbolicOffset()) {
826 Top = cast<SubRegion>(TopKey.getConcreteOffsetRegion());
831 uint64_t
Length = UINT64_MAX;
833 if (Optional<nonloc::ConcreteInt> ExtentCI =
835 const llvm::APSInt &ExtentInt = ExtentCI->getValue();
836 assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned());
839 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(Top)) {
840 if (FR->getDecl()->isBitField())
841 Length = FR->getDecl()->getBitWidthValue(SVB.
getContext());
844 for (ClusterBindings::iterator
I = Cluster.begin(), E = Cluster.end();
846 BindingKey NextKey =
I.getKey();
847 if (NextKey.getRegion() == TopKey.getRegion()) {
853 if (NextKey.getOffset() > TopKey.getOffset() &&
854 NextKey.getOffset() - TopKey.getOffset() <
Length) {
857 Bindings.push_back(*
I);
859 }
else if (NextKey.getOffset() == TopKey.getOffset()) {
866 if (IncludeAllDefaultBindings || NextKey.isDirect())
867 Bindings.push_back(*
I);
870 }
else if (NextKey.hasSymbolicOffset()) {
871 const MemRegion *Base = NextKey.getConcreteOffsetRegion();
876 if (IncludeAllDefaultBindings || NextKey.isDirect())
878 Bindings.push_back(*
I);
879 }
else if (
const SubRegion *BaseSR = dyn_cast<SubRegion>(Base)) {
884 Bindings.push_back(*
I);
893 const SubRegion *Top,
bool IncludeAllDefaultBindings) {
896 IncludeAllDefaultBindings);
903 const MemRegion *ClusterHead = TopKey.getBaseRegion();
905 if (Top == ClusterHead) {
907 return B.remove(Top);
914 if (TopKey.hasSymbolicOffset()) {
915 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
929 Result =
Result.remove(
I->first);
935 if (TopKey.hasSymbolicOffset()) {
936 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
942 return B.remove(ClusterHead);
943 return B.add(ClusterHead,
Result.asImmutableMap());
947 class invalidateRegionsWorker :
public ClusterAnalysis<invalidateRegionsWorker>
957 invalidateRegionsWorker(RegionStoreManager &rm,
960 const Expr *ex,
unsigned count,
966 : ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b),
967 Ex(ex), Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r),
968 GlobalsFilter(GFK) {}
971 void VisitBinding(
SVal V);
973 using ClusterAnalysis::AddToWorkList;
979 bool includeEntireMemorySpace(
const MemRegion *Base);
983 bool isInitiallyIncludedGlobalRegion(
const MemRegion *R);
987 bool invalidateRegionsWorker::AddToWorkList(
const MemRegion *R) {
988 bool doNotInvalidateSuperRegion = ITraits.hasTrait(
991 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
994 void invalidateRegionsWorker::VisitBinding(
SVal V) {
1005 if (Optional<nonloc::LazyCompoundVal> LCS =
1008 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
1010 for (RegionStoreManager::SValListTy::const_iterator
I = Vals.begin(),
1019 void invalidateRegionsWorker::VisitCluster(
const MemRegion *baseR,
1022 bool PreserveRegionsContents =
1023 ITraits.hasTrait(baseR,
1027 for (ClusterBindings::iterator
I = C->begin(), E = C->end();
I !=
E; ++
I)
1028 VisitBinding(
I.getData());
1031 if (!PreserveRegionsContents)
1032 B = B.remove(baseR);
1039 BI = BR->referenced_vars_begin(), BE = BR->referenced_vars_end() ;
1041 const VarRegion *VR = BI.getCapturedRegion();
1053 if (Optional<Loc> L = V.
getAs<
Loc>()) {
1064 IS.insert(SR->getSymbol());
1067 if (PreserveRegionsContents)
1072 Regions->push_back(baseR);
1074 if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
1078 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx, Ctx.IntTy, Count);
1089 if (isInitiallyIncludedGlobalRegion(baseR)) {
1096 if (T->isStructureOrClassType()) {
1105 if (
const ArrayType *AT = Ctx.getAsArrayType(T)) {
1106 bool doNotInvalidateSuperRegion = ITraits.hasTrait(
1110 if (doNotInvalidateSuperRegion) {
1113 Optional<uint64_t> NumElements;
1117 NumElements = CAT->getSize().getZExtValue();
1119 goto conjure_default;
1120 QualType ElementTy = AT->getElementType();
1121 uint64_t ElemSize = Ctx.getTypeSize(ElementTy);
1128 AddToWorkList(SuperR);
1129 goto conjure_default;
1133 uint64_t UpperOffset = LowerOffset + *NumElements * ElemSize;
1134 bool UpperOverflow = UpperOffset < LowerOffset;
1139 goto conjure_default;
1143 goto conjure_default;
1145 for (ClusterBindings::iterator
I = C->begin(), E = C->end();
I !=
E;
1147 const BindingKey &BK =
I.getKey();
1148 Optional<uint64_t> ROffset =
1149 BK.hasSymbolicOffset() ? Optional<uint64_t>() : BK.getOffset();
1154 ((*ROffset >= LowerOffset && *ROffset < UpperOffset) ||
1156 (*ROffset >= LowerOffset || *ROffset < UpperOffset)) ||
1157 (LowerOffset == UpperOffset && *ROffset == LowerOffset))) {
1158 B = B.removeBinding(
I.getKey());
1161 SVal V =
I.getData();
1163 if (R && isa<SymbolicRegion>(R))
1171 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
1172 AT->getElementType(), Count);
1180 B = B.addBinding(baseR, BindingKey::Direct, V);
1183 bool invalidateRegionsWorker::isInitiallyIncludedGlobalRegion(
1185 switch (GlobalsFilter) {
1188 case GFK_SystemOnly:
1194 llvm_unreachable(
"unknown globals filter");
1197 bool invalidateRegionsWorker::includeEntireMemorySpace(
const MemRegion *Base) {
1198 if (isInitiallyIncludedGlobalRegion(Base))
1202 return ITraits.hasTrait(MemSpace,
1211 RegionBindingsRef B,
1212 InvalidatedRegions *Invalidated) {
1216 SVal V = svalBuilder.conjureSymbolVal( (
const void*) GS, Ex, LCtx,
1220 B = B.removeBinding(GS)
1226 Invalidated->push_back(GS);
1231 void RegionStoreManager::populateWorkList(invalidateRegionsWorker &W,
1233 InvalidatedRegions *TopLevelRegions) {
1235 E = Values.end();
I !=
E; ++
I) {
1237 if (Optional<nonloc::LazyCompoundVal> LCS =
1240 const SValListTy &Vals = getInterestingValues(*LCS);
1242 for (SValListTy::const_iterator
I = Vals.begin(),
1243 E = Vals.end();
I !=
E; ++
I) {
1246 if (
const MemRegion *R = (*I).getAsRegion())
1253 if (TopLevelRegions)
1254 TopLevelRegions->push_back(R);
1262 RegionStoreManager::invalidateRegions(
Store store,
1264 const Expr *Ex,
unsigned Count,
1269 InvalidatedRegions *TopLevelRegions,
1270 InvalidatedRegions *Invalidated) {
1274 GlobalsFilter = GFK_SystemOnly;
1276 GlobalsFilter = GFK_All;
1278 GlobalsFilter = GFK_None;
1281 RegionBindingsRef B = getRegionBindings(store);
1282 invalidateRegionsWorker W(*
this, StateMgr, B, Ex, Count, LCtx, IS, ITraits,
1283 Invalidated, GlobalsFilter);
1286 W.GenerateClusters();
1289 populateWorkList(W, Values, TopLevelRegions);
1294 B = W.getRegionBindings();
1300 switch (GlobalsFilter) {
1302 B = invalidateGlobalRegion(MemRegion::GlobalInternalSpaceRegionKind,
1303 Ex, Count, LCtx, B, Invalidated);
1305 case GFK_SystemOnly:
1306 B = invalidateGlobalRegion(MemRegion::GlobalSystemSpaceRegionKind,
1307 Ex, Count, LCtx, B, Invalidated);
1313 return StoreRef(B.asStore(), *
this);
1324 SVal Size = cast<SubRegion>(R)->getExtent(svalBuilder);
1325 const llvm::APSInt *SizeInt = svalBuilder.getKnownValue(state, Size);
1331 if (Ctx.getAsVariableArrayType(EleTy)) {
1338 CharUnits EleSize = Ctx.getTypeSizeInChars(EleTy);
1343 return svalBuilder.makeIntVal(RegionSize / EleSize,
false);
1365 NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex();
1392 if (isa<BlockDataRegion>(MR)) {
1396 if (isa<AllocaRegion>(MR) ||
1397 isa<SymbolicRegion>(MR) ||
1398 isa<CodeTextRegion>(MR)) {
1400 if (
const TypedRegion *TR = dyn_cast<TypedRegion>(MR))
1407 MR = GetElementZeroRegion(cast<SubRegion>(MR), T);
1417 if (RTy->isAnyComplexType())
1428 if (RTy->isStructureOrClassType())
1429 return getBindingForStruct(B, R);
1432 if (RTy->isUnionType())
1433 return createLazyBinding(B, R);
1435 if (RTy->isArrayType()) {
1436 if (RTy->isConstantArrayType())
1437 return getBindingForArray(B, R);
1443 if (RTy->isVectorType())
1446 if (
const FieldRegion* FR = dyn_cast<FieldRegion>(R))
1447 return CastRetrievedVal(getBindingForField(B, FR), FR, T,
false);
1455 return CastRetrievedVal(getBindingForElement(B, ER), ER, T,
false);
1465 return CastRetrievedVal(getBindingForObjCIvar(B, IVR), IVR, T,
false);
1468 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
1475 return CastRetrievedVal(getBindingForVar(B, VR), VR, T,
false);
1478 const SVal *V = B.lookup(R, BindingKey::Direct);
1496 return svalBuilder.getRegionValueSymbolVal(R);
1502 RegionTy = TVR->getValueType();
1517 static Optional<nonloc::LazyCompoundVal>
1519 const SubRegion *R,
bool AllowSubregionBindings) {
1520 Optional<SVal> V = B.getDefaultBinding(R);
1531 if (!RegionTy.
isNull() &&
1533 QualType SourceRegionTy = LCV->getRegion()->getValueType();
1538 if (!AllowSubregionBindings) {
1544 if (Bindings.size() > 1)
1552 std::pair<Store, const SubRegion *>
1556 if (originalRegion != R) {
1557 if (Optional<nonloc::LazyCompoundVal> V =
1559 return std::make_pair(V->getStore(), V->getRegion());
1562 typedef std::pair<Store, const SubRegion *> StoreRegionPair;
1563 StoreRegionPair
Result = StoreRegionPair();
1566 Result = findLazyBinding(B, cast<SubRegion>(ER->getSuperRegion()),
1570 Result.second = MRMgr.getElementRegionWithSuper(ER, Result.second);
1572 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
1573 Result = findLazyBinding(B, cast<SubRegion>(FR->getSuperRegion()),
1577 Result.second = MRMgr.getFieldRegionWithSuper(FR, Result.second);
1580 dyn_cast<CXXBaseObjectRegion>(R)) {
1583 Result = findLazyBinding(B, cast<SubRegion>(BaseReg->getSuperRegion()),
1587 Result.second = MRMgr.getCXXBaseObjectRegionWithSuper(BaseReg,
1601 if (
const Optional<SVal> &V = B.getDirectBinding(R))
1607 if (
const StringRegion *StrR=dyn_cast<StringRegion>(superR)) {
1610 QualType T = Ctx.getAsArrayType(StrR->getValueType())->getElementType();
1617 int64_t i = CI->getValue().getSExtValue();
1628 return svalBuilder.makeIntVal(c, T);
1633 if (isa<CodeTextRegion>(superR))
1649 dyn_cast_or_null<TypedValueRegion>(O.
getRegion())) {
1650 QualType baseT = baseR->getValueType();
1654 if (Ctx.getTypeSizeInChars(baseT) >= Ctx.getTypeSizeInChars(elemT)) {
1655 if (
const Optional<SVal> &V = B.getDirectBinding(superR)) {
1657 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1669 return getBindingForFieldOrElementCommon(B, R, R->
getElementType());
1676 if (
const Optional<SVal> &V = B.getDirectBinding(R))
1680 return getBindingForFieldOrElementCommon(B, R, Ty);
1689 if (
const Optional<SVal> &D = B.getDefaultBinding(superR)) {
1690 const SVal &val = D.getValue();
1692 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1695 return svalBuilder.makeZeroVal(Ty);
1706 llvm_unreachable(
"Unknown default value");
1712 SVal RegionStoreManager::getLazyBinding(
const SubRegion *LazyBindingRegion,
1713 RegionBindingsRef LazyBinding) {
1715 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(LazyBindingRegion))
1716 Result = getBindingForElement(LazyBinding, ER);
1718 Result = getBindingForField(LazyBinding,
1719 cast<FieldRegion>(LazyBindingRegion));
1750 Store lazyBindingStore =
nullptr;
1751 const SubRegion *lazyBindingRegion =
nullptr;
1752 std::tie(lazyBindingStore, lazyBindingRegion) = findLazyBinding(B, R, R);
1753 if (lazyBindingRegion)
1754 return getLazyBinding(lazyBindingRegion,
1755 getRegionBindings(lazyBindingStore));
1759 bool hasSymbolicIndex =
false;
1775 bool hasPartialLazyBinding =
false;
1780 if (Optional<SVal> D = getBindingForDerivedDefaultValue(B, Base, R, Ty)) {
1782 hasPartialLazyBinding =
true;
1789 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(Base)) {
1790 NonLoc index = ER->getIndex();
1792 hasSymbolicIndex =
true;
1801 if (isa<ElementRegion>(R)) {
1806 if (typedSuperR->getValueType()->isVectorType())
1815 if (hasSymbolicIndex)
1818 if (!hasPartialLazyBinding)
1823 return svalBuilder.getRegionValueSymbolVal(R);
1829 if (
const Optional<SVal> &V = B.getDirectBinding(R))
1835 if (
const Optional<SVal> &V = B.getDefaultBinding(superR)) {
1837 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1843 return getBindingForLazySymbol(R);
1850 if (
const Optional<SVal> &V = B.getDirectBinding(R))
1858 if (isa<StackArgumentsSpaceRegion>(MS))
1859 return svalBuilder.getRegionValueSymbolVal(R);
1864 if (Optional<SVal> V = svalBuilder.getConstantVal(Init))
1869 if (isa<UnknownSpaceRegion>(MS))
1870 return svalBuilder.getRegionValueSymbolVal(R);
1872 if (isa<GlobalsSpaceRegion>(MS)) {
1879 if (isa<StaticGlobalSpaceRegion>(MS))
1880 return svalBuilder.makeZeroVal(T);
1882 if (Optional<SVal> V = getBindingForDerivedDefaultValue(B, MS, R, T)) {
1884 return V.getValue();
1887 return svalBuilder.getRegionValueSymbolVal(R);
1895 return svalBuilder.getRegionValueSymbolVal(R);
1898 const RegionStoreManager::SValListTy &
1901 LazyBindingsMapTy::iterator
I = LazyBindingsMap.find(LCV.
getCVData());
1902 if (I != LazyBindingsMap.end())
1909 RegionBindingsRef B = getRegionBindings(LCV.
getStore());
1915 return (LazyBindingsMap[LCV.
getCVData()] = std::move(List));
1927 if (Optional<nonloc::LazyCompoundVal> InnerLCV =
1929 const SValListTy &InnerList = getInterestingValues(*InnerLCV);
1930 List.insert(List.end(), InnerList.begin(), InnerList.end());
1937 return (LazyBindingsMap[LCV.
getCVData()] = std::move(List));
1942 if (Optional<nonloc::LazyCompoundVal> V =
1946 return svalBuilder.makeLazyCompoundVal(
StoreRef(B.asStore(), *
this), R);
1953 return CRD->getNumBases() == 0;
1963 return createLazyBinding(B, R);
1968 assert(Ctx.getAsConstantArrayType(R->
getValueType()) &&
1969 "Only constant array types can have compound bindings.");
1971 return createLazyBinding(B, R);
1974 bool RegionStoreManager::includedInBindings(
Store store,
1976 RegionBindingsRef B = getRegionBindings(store);
1980 if (B.lookup(region))
1984 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI) {
1986 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
1988 const SVal &D = CI.getData();
2004 if (
const MemRegion* R = LV->getRegion())
2005 return StoreRef(getRegionBindings(ST).removeBinding(R)
2007 .getRootWithoutRetain(),
2025 return bindArray(B, TR, V);
2027 return bindStruct(B, TR, V);
2029 return bindVector(B, TR, V);
2031 return bindAggregate(B, TR, V);
2037 QualType T = SR->getSymbol()->getType();
2041 R = GetElementZeroRegion(SR, T);
2045 RegionBindingsRef NewB = removeSubRegionBindings(B, cast<SubRegion>(R));
2056 V = svalBuilder.makeNull();
2058 V = svalBuilder.makeZeroVal(T);
2062 V = svalBuilder.makeZeroVal(Ctx.IntTy);
2083 Optional<uint64_t> Size;
2086 Size = CAT->getSize().getZExtValue();
2090 const StringRegion *S = cast<StringRegion>(MRV->getRegion());
2093 StoreRef store(B.asStore(), *
this);
2096 return bindAggregate(B, R, LCV);
2101 return bindAggregate(B, R, Init);
2111 RegionBindingsRef NewB(B);
2113 for (; Size.hasValue() ? i < Size.getValue() :
true ; ++i, ++VI) {
2118 const NonLoc &Idx = svalBuilder.makeArrayIndex(i);
2119 const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx);
2122 NewB = bindStruct(NewB, ER, *VI);
2124 NewB = bindArray(NewB, ER, *VI);
2131 if (Size.hasValue() && i < Size.getValue())
2132 NewB = setImplicitDefaultValue(NewB, R, ElementTy);
2146 return bindAggregate(B, R, V);
2155 QualType ElemType = VT->getElementType();
2158 unsigned index = 0, numElements = VT->getNumElements();
2159 RegionBindingsRef NewB(B);
2161 for ( ; index != numElements ; ++index) {
2165 NonLoc Idx = svalBuilder.makeArrayIndex(index);
2166 const ElementRegion *ER = MRMgr.getElementRegion(ElemType, Idx, R, Ctx);
2169 NewB = bindArray(NewB, ER, *VI);
2171 NewB = bindStruct(NewB, ER, *VI);
2178 Optional<RegionBindingsRef>
2185 if (
const CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(RD))
2186 if (
Class->getNumBases() != 0 ||
Class->getNumVBases() != 0)
2189 for (
const auto *FD : RD->
fields()) {
2190 if (FD->isUnnamedBitfield())
2195 if (Fields.size() == SmallStructLimit)
2202 Fields.push_back(FD);
2205 RegionBindingsRef NewB = B;
2207 for (FieldVector::iterator I = Fields.begin(), E = Fields.end(); I !=
E; ++
I){
2209 SVal V = getBindingForField(getRegionBindings(LCV.
getStore()), SourceFR);
2211 const FieldRegion *DestFR = MRMgr.getFieldRegion(*I, R);
2221 if (!Features.supportsFields())
2230 if (!RD->isCompleteDefinition())
2234 if (Optional<nonloc::LazyCompoundVal> LCV =
2236 if (Optional<RegionBindingsRef> NewB = tryBindSmallStruct(B, R, RD, *LCV))
2238 return bindAggregate(B, R, V);
2241 return bindAggregate(B, R, V);
2253 RegionBindingsRef NewB(B);
2255 for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI) {
2261 if (FI->isUnnamedBitfield())
2265 const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
2268 NewB = bindArray(NewB, FR, *VI);
2270 NewB = bindStruct(NewB, FR, *VI);
2279 svalBuilder.makeIntVal(0,
false));
2299 class removeDeadBindingsWorker :
2300 public ClusterAnalysis<removeDeadBindingsWorker> {
2306 removeDeadBindingsWorker(RegionStoreManager &rm,
2310 : ClusterAnalysis<removeDeadBindingsWorker>(rm, stateMgr, b),
2311 SymReaper(symReaper), CurrentLCtx(LCtx) {}
2316 using ClusterAnalysis<removeDeadBindingsWorker>::VisitCluster;
2318 using ClusterAnalysis::AddToWorkList;
2322 bool UpdatePostponed();
2323 void VisitBinding(
SVal V);
2327 bool removeDeadBindingsWorker::AddToWorkList(
const MemRegion *R) {
2329 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
2332 void removeDeadBindingsWorker::VisitAddedToCluster(
const MemRegion *baseR,
2335 if (
const VarRegion *VR = dyn_cast<VarRegion>(baseR)) {
2336 if (SymReaper.isLive(VR))
2337 AddToWorkList(baseR, &C);
2342 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
2343 if (SymReaper.isLive(SR->getSymbol()))
2344 AddToWorkList(SR, &C);
2346 Postponed.push_back(SR);
2351 if (isa<NonStaticGlobalSpaceRegion>(baseR)) {
2352 AddToWorkList(baseR, &C);
2357 if (
const CXXThisRegion *TR = dyn_cast<CXXThisRegion>(baseR)) {
2362 (RegCtx == CurrentLCtx || RegCtx->isParentOf(CurrentLCtx)))
2363 AddToWorkList(TR, &C);
2367 void removeDeadBindingsWorker::VisitCluster(
const MemRegion *baseR,
2374 if (
const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(baseR))
2375 SymReaper.markLive(SymR->getSymbol());
2377 for (ClusterBindings::iterator I = C->begin(), E = C->end(); I !=
E; ++
I) {
2379 SymReaper.markElementIndicesLive(I.getKey().getRegion());
2381 VisitBinding(I.getData());
2385 void removeDeadBindingsWorker::VisitBinding(
SVal V) {
2387 if (Optional<nonloc::LazyCompoundVal> LCS =
2390 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
2392 for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
2403 SymReaper.markLive(R);
2408 E = BR->referenced_vars_end();
2409 for ( ; I !=
E; ++
I)
2418 SymReaper.markLive(*SI);
2421 bool removeDeadBindingsWorker::UpdatePostponed() {
2424 bool changed =
false;
2427 I = Postponed.begin(), E = Postponed.end() ; I !=
E ; ++
I) {
2429 if (SymReaper.isLive(SR->getSymbol())) {
2430 changed |= AddToWorkList(SR);
2439 StoreRef RegionStoreManager::removeDeadBindings(
Store store,
2442 RegionBindingsRef B = getRegionBindings(store);
2443 removeDeadBindingsWorker W(*
this, StateMgr, B, SymReaper, LCtx);
2444 W.GenerateClusters();
2449 W.AddToWorkList(*I);
2452 do W.RunWorkList();
while (W.UpdatePostponed());
2457 for (RegionBindingsRef::iterator I = B.begin(), E = B.end(); I !=
E; ++
I) {
2461 if (W.isVisited(Base))
2472 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
2474 SVal X = CI.getData();
2476 for (; SI != SE; ++SI)
2481 return StoreRef(B.asStore(), *
this);
2488 void RegionStoreManager::print(
Store store, raw_ostream &OS,
2489 const char* nl,
const char *sep) {
2490 RegionBindingsRef B = getRegionBindings(store);
2491 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 visits 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
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.
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...
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.
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 field is ...
Iterator over symbols that the current symbol depends on.
const void * getStore() const