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")
133 static const bool value =
true;
153 class RegionBindingsRef :
public llvm::ImmutableMapRef<const MemRegion *,
155 ClusterBindings::Factory *CBFactory;
158 typedef llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>
161 RegionBindingsRef(ClusterBindings::Factory &CBFactory,
162 const RegionBindings::TreeTy *
T,
163 RegionBindings::TreeTy::Factory *F)
164 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(
T, F),
165 CBFactory(&CBFactory) {}
167 RegionBindingsRef(
const ParentTy &P, ClusterBindings::Factory &CBFactory)
168 : llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(
P),
169 CBFactory(&CBFactory) {}
171 RegionBindingsRef add(key_type_ref K, data_type_ref D)
const {
172 return RegionBindingsRef(static_cast<const ParentTy *>(
this)->add(K, D),
176 RegionBindingsRef
remove(key_type_ref K)
const {
177 return RegionBindingsRef(static_cast<const ParentTy *>(
this)->
remove(K),
181 RegionBindingsRef addBinding(BindingKey K,
SVal V)
const;
183 RegionBindingsRef addBinding(
const MemRegion *R,
184 BindingKey::Kind k,
SVal V)
const;
186 const SVal *lookup(BindingKey K)
const;
187 const SVal *lookup(
const MemRegion *R, BindingKey::Kind k)
const;
188 using llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>::lookup;
190 RegionBindingsRef removeBinding(BindingKey K);
192 RegionBindingsRef removeBinding(
const MemRegion *R,
195 RegionBindingsRef removeBinding(
const MemRegion *R) {
196 return removeBinding(R, BindingKey::Direct).
207 Store asStore()
const {
208 return asImmutableMap().getRootWithoutRetain();
211 void dump(raw_ostream &OS,
const char *nl)
const {
212 for (iterator I = begin(), E = end(); I != E; ++I) {
213 const ClusterBindings &Cluster = I.getData();
214 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
216 OS <<
' ' << CI.getKey() <<
" : " << CI.getData() << nl;
222 LLVM_DUMP_METHOD
void dump()
const {
dump(llvm::errs(),
"\n"); }
235 if (TR->getValueType()->isUnionType())
241 RegionBindingsRef RegionBindingsRef::addBinding(BindingKey K,
SVal V)
const {
242 const MemRegion *Base = K.getBaseRegion();
244 const ClusterBindings *ExistingCluster = lookup(Base);
245 ClusterBindings Cluster =
246 (ExistingCluster ? *ExistingCluster : CBFactory->getEmptyMap());
248 ClusterBindings NewCluster = CBFactory->add(Cluster, K, V);
249 return add(Base, NewCluster);
253 RegionBindingsRef RegionBindingsRef::addBinding(
const MemRegion *R,
259 const SVal *RegionBindingsRef::lookup(BindingKey K)
const {
260 const ClusterBindings *Cluster = lookup(K.getBaseRegion());
263 return Cluster->lookup(K);
267 BindingKey::Kind k)
const {
271 RegionBindingsRef RegionBindingsRef::removeBinding(BindingKey K) {
272 const MemRegion *Base = K.getBaseRegion();
273 const ClusterBindings *Cluster = lookup(Base);
277 ClusterBindings NewCluster = CBFactory->remove(*Cluster, K);
278 if (NewCluster.isEmpty())
280 return add(Base, NewCluster);
283 RegionBindingsRef RegionBindingsRef::removeBinding(
const MemRegion *R,
293 struct minimal_features_tag {};
294 struct maximal_features_tag {};
296 class RegionStoreFeatures {
299 RegionStoreFeatures(minimal_features_tag) :
300 SupportsFields(
false) {}
302 RegionStoreFeatures(maximal_features_tag) :
303 SupportsFields(
true) {}
305 void enableFields(
bool t) { SupportsFields = t; }
307 bool supportsFields()
const {
return SupportsFields; }
316 class invalidateRegionsWorker;
320 const RegionStoreFeatures Features;
322 RegionBindings::Factory RBFactory;
323 mutable ClusterBindings::Factory CBFactory;
325 typedef std::vector<SVal> SValListTy;
328 SValListTy> LazyBindingsMapTy;
329 LazyBindingsMapTy LazyBindingsMap;
339 unsigned SmallStructLimit;
343 void populateWorkList(invalidateRegionsWorker &W,
345 InvalidatedRegions *TopLevelRegions);
351 SmallStructLimit(0) {
352 if (
SubEngine *Eng = StateMgr.getOwningEngine()) {
363 RegionBindingsRef setImplicitDefaultValue(RegionBindingsConstRef B,
375 return StoreRef(RBFactory.getEmptyMap().getRootWithoutRetain(), *
this);
386 InvalidatedRegions *Invalidated);
390 const Expr *E,
unsigned Count,
395 InvalidatedRegions *Invalidated,
396 InvalidatedRegions *InvalidatedTopLevel)
override;
401 RegionBindingsRef removeSubRegionBindings(RegionBindingsConstRef B,
407 return StoreRef(bind(getRegionBindings(store), LV, V).asStore(), *
this);
410 RegionBindingsRef bind(RegionBindingsConstRef B,
Loc LV,
SVal V);
423 if (R->
getKind() == MemRegion::CXXBaseObjectRegionKind &&
424 cast<CXXBaseObjectRegion>(R)->getDecl()->isEmpty())
427 RegionBindingsRef B = getRegionBindings(store);
428 assert(!B.lookup(R, BindingKey::Direct));
432 const SubRegion *SR = cast<SubRegion>(R);
435 "A default value must come from a super-region");
436 B = removeSubRegionBindings(B, SR);
438 B = B.addBinding(Key, V);
441 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *
this);
460 RegionBindingsRef bindStruct(RegionBindingsConstRef B,
464 RegionBindingsRef bindVector(RegionBindingsConstRef B,
467 RegionBindingsRef bindArray(RegionBindingsConstRef B,
473 RegionBindingsRef bindAggregate(RegionBindingsConstRef B,
482 void incrementReferenceCount(
Store store)
override {
483 getRegionBindings(store).manualRetain();
489 void decrementReferenceCount(
Store store)
override {
490 getRegionBindings(store).manualRelease();
493 bool includedInBindings(
Store store,
const MemRegion *region)
const override;
509 return getBinding(getRegionBindings(S), L, T);
513 RegionBindingsRef B = getRegionBindings(S);
524 SVal getBindingForField(RegionBindingsConstRef B,
const FieldRegion *R);
528 SVal getBindingForVar(RegionBindingsConstRef B,
const VarRegion *R);
532 SVal getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
537 RegionBindingsRef LazyBinding);
553 Optional<SVal> getBindingForDerivedDefaultValue(RegionBindingsConstRef B,
562 std::pair<Store, const SubRegion *>
563 findLazyBinding(RegionBindingsConstRef B,
const SubRegion *R,
596 RegionBindingsRef getRegionBindings(
Store store)
const {
597 return RegionBindingsRef(CBFactory,
598 static_cast<const RegionBindings::TreeTy*>(store),
599 RBFactory.getTreeFactory());
602 void print(
Store store, raw_ostream &Out,
const char* nl,
603 const char *sep)
override;
605 void iterBindings(
Store store, BindingsHandler& f)
override {
606 RegionBindingsRef B = getRegionBindings(store);
607 for (RegionBindingsRef::iterator I = B.begin(), E = B.end(); I != E; ++I) {
608 const ClusterBindings &Cluster = I.getData();
609 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
611 const BindingKey &K = CI.getKey();
614 if (
const SubRegion *R = dyn_cast<SubRegion>(K.getRegion())) {
616 if (!f.HandleBinding(*
this, store, R, CI.getData()))
630 std::unique_ptr<StoreManager>
632 RegionStoreFeatures F = maximal_features_tag();
633 return llvm::make_unique<RegionStoreManager>(StMgr, F);
636 std::unique_ptr<StoreManager>
638 RegionStoreFeatures F = minimal_features_tag();
639 F.enableFields(
true);
640 return llvm::make_unique<RegionStoreManager>(StMgr, F);
660 template <
typename DERIVED>
661 class ClusterAnalysis {
663 typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
664 typedef const MemRegion * WorkListElement;
667 llvm::SmallPtrSet<const ClusterBindings *, 16> Visited;
671 RegionStoreManager &RM;
679 const ClusterBindings *getCluster(
const MemRegion *R) {
686 bool includeEntireMemorySpace(
const MemRegion *Base) {
696 RegionBindingsRef getRegionBindings()
const {
return B; }
699 return Visited.count(getCluster(R));
702 void GenerateClusters() {
704 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end();
708 const ClusterBindings &Cluster = RI.getData();
709 assert(!Cluster.isEmpty() &&
"Empty clusters should be removed");
710 static_cast<DERIVED*
>(
this)->VisitAddedToCluster(Base, Cluster);
714 if (static_cast<DERIVED*>(
this)->includeEntireMemorySpace(Base))
715 AddToWorkList(WorkListElement(Base), &Cluster);
719 bool AddToWorkList(WorkListElement E,
const ClusterBindings *C) {
720 if (C && !Visited.insert(C).second)
727 return static_cast<DERIVED*
>(
this)->AddToWorkList(R);
731 while (!WL.empty()) {
732 WorkListElement E = WL.pop_back_val();
735 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, getCluster(BaseR));
739 void VisitAddedToCluster(
const MemRegion *baseR,
const ClusterBindings &C) {}
740 void VisitCluster(
const MemRegion *baseR,
const ClusterBindings *C) {}
742 void VisitCluster(
const MemRegion *BaseR,
const ClusterBindings *C,
744 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, C);
753 bool RegionStoreManager::scanReachableSymbols(
Store S,
const MemRegion *R,
755 assert(R == R->
getBaseRegion() &&
"Should only be called for base regions");
756 RegionBindingsRef B = getRegionBindings(S);
757 const ClusterBindings *Cluster = B.lookup(R);
762 for (ClusterBindings::iterator RI = Cluster->begin(), RE = Cluster->end();
764 if (!Callbacks.
scan(RI.getData()))
778 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
780 const MemRegion *Base = K.getConcreteOffsetRegion();
784 if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R))
786 Fields.push_back(FR->getDecl());
788 R = cast<SubRegion>(R)->getSuperRegion();
793 assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
798 FieldVector FieldsInBindingKey;
801 ptrdiff_t Delta = FieldsInBindingKey.size() - Fields.size();
803 return std::equal(FieldsInBindingKey.begin() + Delta,
804 FieldsInBindingKey.end(),
807 return std::equal(FieldsInBindingKey.begin(), FieldsInBindingKey.end(),
808 Fields.begin() - Delta);
824 bool IncludeAllDefaultBindings) {
825 FieldVector FieldsInSymbolicSubregions;
826 if (TopKey.hasSymbolicOffset()) {
828 Top = cast<SubRegion>(TopKey.getConcreteOffsetRegion());
833 uint64_t Length = UINT64_MAX;
837 const llvm::APSInt &ExtentInt = ExtentCI->getValue();
838 assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned());
841 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(Top)) {
842 if (FR->getDecl()->isBitField())
843 Length = FR->getDecl()->getBitWidthValue(SVB.
getContext());
846 for (ClusterBindings::iterator I = Cluster.begin(), E = Cluster.end();
848 BindingKey NextKey = I.getKey();
849 if (NextKey.getRegion() == TopKey.getRegion()) {
855 if (NextKey.getOffset() > TopKey.getOffset() &&
856 NextKey.getOffset() - TopKey.getOffset() < Length) {
859 Bindings.push_back(*I);
861 }
else if (NextKey.getOffset() == TopKey.getOffset()) {
868 if (IncludeAllDefaultBindings || NextKey.isDirect())
869 Bindings.push_back(*I);
872 }
else if (NextKey.hasSymbolicOffset()) {
873 const MemRegion *Base = NextKey.getConcreteOffsetRegion();
878 if (IncludeAllDefaultBindings || NextKey.isDirect())
880 Bindings.push_back(*I);
881 }
else if (
const SubRegion *BaseSR = dyn_cast<SubRegion>(Base)) {
886 Bindings.push_back(*I);
895 const SubRegion *Top,
bool IncludeAllDefaultBindings) {
898 IncludeAllDefaultBindings);
902 RegionStoreManager::removeSubRegionBindings(RegionBindingsConstRef B,
905 const MemRegion *ClusterHead = TopKey.getBaseRegion();
907 if (Top == ClusterHead) {
909 return B.remove(Top);
912 const ClusterBindings *Cluster = B.lookup(ClusterHead);
916 if (TopKey.hasSymbolicOffset()) {
917 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
927 ClusterBindingsRef Result(*Cluster, CBFactory);
931 Result = Result.remove(I->first);
937 if (TopKey.hasSymbolicOffset()) {
938 const SubRegion *Concrete = TopKey.getConcreteOffsetRegion();
943 if (Result.isEmpty())
944 return B.remove(ClusterHead);
945 return B.add(ClusterHead, Result.asImmutableMap());
949 class invalidateRegionsWorker :
public ClusterAnalysis<invalidateRegionsWorker>
959 invalidateRegionsWorker(RegionStoreManager &rm,
962 const Expr *ex,
unsigned count,
968 : ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b),
969 Ex(ex), Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r),
970 GlobalsFilter(GFK) {}
972 void VisitCluster(
const MemRegion *baseR,
const ClusterBindings *C);
973 void VisitBinding(
SVal V);
975 using ClusterAnalysis::AddToWorkList;
981 bool includeEntireMemorySpace(
const MemRegion *Base);
985 bool isInitiallyIncludedGlobalRegion(
const MemRegion *R);
989 bool invalidateRegionsWorker::AddToWorkList(
const MemRegion *R) {
990 bool doNotInvalidateSuperRegion = ITraits.hasTrait(
993 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
996 void invalidateRegionsWorker::VisitBinding(
SVal V) {
1010 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
1012 for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
1021 void invalidateRegionsWorker::VisitCluster(
const MemRegion *baseR,
1022 const ClusterBindings *C) {
1024 bool PreserveRegionsContents =
1025 ITraits.hasTrait(baseR,
1029 for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E; ++I)
1030 VisitBinding(I.getData());
1033 if (!PreserveRegionsContents)
1034 B = B.remove(baseR);
1041 BI = BR->referenced_vars_begin(), BE = BR->referenced_vars_end() ;
1043 const VarRegion *VR = BI.getCapturedRegion();
1056 if (
const MemRegion *LR = L->getAsRegion())
1066 IS.insert(SR->getSymbol());
1069 if (PreserveRegionsContents)
1074 Regions->push_back(baseR);
1076 if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
1080 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx, Ctx.IntTy, Count);
1091 if (isInitiallyIncludedGlobalRegion(baseR)) {
1098 if (T->isStructureOrClassType()) {
1107 if (
const ArrayType *AT = Ctx.getAsArrayType(T)) {
1108 bool doNotInvalidateSuperRegion = ITraits.hasTrait(
1112 if (doNotInvalidateSuperRegion) {
1119 NumElements = CAT->getSize().getZExtValue();
1121 goto conjure_default;
1122 QualType ElementTy = AT->getElementType();
1123 uint64_t ElemSize = Ctx.getTypeSize(ElementTy);
1130 AddToWorkList(SuperR);
1131 goto conjure_default;
1135 uint64_t UpperOffset = LowerOffset + *NumElements * ElemSize;
1136 bool UpperOverflow = UpperOffset < LowerOffset;
1141 goto conjure_default;
1143 const ClusterBindings *C = B.lookup(SuperR);
1145 goto conjure_default;
1147 for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E;
1149 const BindingKey &BK = I.getKey();
1156 ((*ROffset >= LowerOffset && *ROffset < UpperOffset) ||
1158 (*ROffset >= LowerOffset || *ROffset < UpperOffset)) ||
1159 (LowerOffset == UpperOffset && *ROffset == LowerOffset))) {
1160 B = B.removeBinding(I.getKey());
1163 SVal V = I.getData();
1165 if (R && isa<SymbolicRegion>(R))
1173 svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
1174 AT->getElementType(), Count);
1182 B = B.addBinding(baseR, BindingKey::Direct, V);
1185 bool invalidateRegionsWorker::isInitiallyIncludedGlobalRegion(
1187 switch (GlobalsFilter) {
1190 case GFK_SystemOnly:
1196 llvm_unreachable(
"unknown globals filter");
1199 bool invalidateRegionsWorker::includeEntireMemorySpace(
const MemRegion *Base) {
1200 if (isInitiallyIncludedGlobalRegion(Base))
1204 return ITraits.hasTrait(MemSpace,
1213 RegionBindingsRef B,
1214 InvalidatedRegions *Invalidated) {
1218 SVal V = svalBuilder.conjureSymbolVal( (
const void*) GS, Ex, LCtx,
1222 B = B.removeBinding(GS)
1228 Invalidated->push_back(GS);
1233 void RegionStoreManager::populateWorkList(invalidateRegionsWorker &W,
1235 InvalidatedRegions *TopLevelRegions) {
1237 E = Values.end(); I != E; ++I) {
1242 const SValListTy &Vals = getInterestingValues(*LCS);
1244 for (SValListTy::const_iterator I = Vals.begin(),
1245 E = Vals.end(); I != E; ++I) {
1248 if (
const MemRegion *R = (*I).getAsRegion())
1255 if (TopLevelRegions)
1256 TopLevelRegions->push_back(R);
1264 RegionStoreManager::invalidateRegions(
Store store,
1266 const Expr *Ex,
unsigned Count,
1271 InvalidatedRegions *TopLevelRegions,
1272 InvalidatedRegions *Invalidated) {
1276 GlobalsFilter = GFK_SystemOnly;
1278 GlobalsFilter = GFK_All;
1280 GlobalsFilter = GFK_None;
1283 RegionBindingsRef B = getRegionBindings(store);
1284 invalidateRegionsWorker W(*
this, StateMgr, B, Ex, Count, LCtx, IS, ITraits,
1285 Invalidated, GlobalsFilter);
1288 W.GenerateClusters();
1291 populateWorkList(W, Values, TopLevelRegions);
1296 B = W.getRegionBindings();
1302 switch (GlobalsFilter) {
1304 B = invalidateGlobalRegion(MemRegion::GlobalInternalSpaceRegionKind,
1305 Ex, Count, LCtx, B, Invalidated);
1307 case GFK_SystemOnly:
1308 B = invalidateGlobalRegion(MemRegion::GlobalSystemSpaceRegionKind,
1309 Ex, Count, LCtx, B, Invalidated);
1315 return StoreRef(B.asStore(), *
this);
1326 SVal Size = cast<SubRegion>(R)->getExtent(svalBuilder);
1327 const llvm::APSInt *SizeInt = svalBuilder.getKnownValue(state, Size);
1333 if (Ctx.getAsVariableArrayType(EleTy)) {
1340 CharUnits EleSize = Ctx.getTypeSizeInChars(EleTy);
1345 return svalBuilder.makeIntVal(RegionSize / EleSize,
false);
1367 NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex();
1375 SVal RegionStoreManager::getBinding(RegionBindingsConstRef B,
Loc L,
QualType T) {
1394 if (isa<BlockDataRegion>(MR)) {
1398 if (!isa<TypedValueRegion>(MR)) {
1400 if (
const TypedRegion *TR = dyn_cast<TypedRegion>(MR))
1402 else if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
1404 else if (isa<AllocaRegion>(MR))
1407 assert(!T.
isNull() &&
"Unable to auto-detect binding type!");
1408 assert(!T->
isVoidType() &&
"Attempting to dereference a void pointer!");
1409 MR = GetElementZeroRegion(cast<SubRegion>(MR), T);
1419 if (RTy->isAnyComplexType())
1430 if (RTy->isStructureOrClassType())
1431 return getBindingForStruct(B, R);
1434 if (RTy->isUnionType())
1435 return createLazyBinding(B, R);
1437 if (RTy->isArrayType()) {
1438 if (RTy->isConstantArrayType())
1439 return getBindingForArray(B, R);
1445 if (RTy->isVectorType())
1448 if (
const FieldRegion* FR = dyn_cast<FieldRegion>(R))
1449 return CastRetrievedVal(getBindingForField(B, FR), FR,
T,
false);
1457 return CastRetrievedVal(getBindingForElement(B, ER), ER, T,
false);
1467 return CastRetrievedVal(getBindingForObjCIvar(B, IVR), IVR, T,
false);
1470 if (
const VarRegion *VR = dyn_cast<VarRegion>(R)) {
1477 return CastRetrievedVal(getBindingForVar(B, VR), VR, T,
false);
1480 const SVal *V = B.lookup(R, BindingKey::Direct);
1498 return svalBuilder.getRegionValueSymbolVal(R);
1504 RegionTy = TVR->getValueType();
1507 RegionTy = SR->getSymbol()->getType();
1521 const SubRegion *R,
bool AllowSubregionBindings) {
1533 if (!RegionTy.
isNull() &&
1535 QualType SourceRegionTy = LCV->getRegion()->getValueType();
1540 if (!AllowSubregionBindings) {
1546 if (Bindings.size() > 1)
1554 std::pair<Store, const SubRegion *>
1555 RegionStoreManager::findLazyBinding(RegionBindingsConstRef B,
1558 if (originalRegion != R) {
1561 return std::make_pair(V->getStore(), V->getRegion());
1564 typedef std::pair<Store, const SubRegion *> StoreRegionPair;
1565 StoreRegionPair Result = StoreRegionPair();
1568 Result = findLazyBinding(B, cast<SubRegion>(ER->getSuperRegion()),
1572 Result.second = MRMgr.getElementRegionWithSuper(ER, Result.second);
1574 }
else if (
const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
1575 Result = findLazyBinding(B, cast<SubRegion>(FR->getSuperRegion()),
1579 Result.second = MRMgr.getFieldRegionWithSuper(FR, Result.second);
1582 dyn_cast<CXXBaseObjectRegion>(R)) {
1585 Result = findLazyBinding(B, cast<SubRegion>(BaseReg->getSuperRegion()),
1589 Result.second = MRMgr.getCXXBaseObjectRegionWithSuper(BaseReg,
1596 SVal RegionStoreManager::getBindingForElement(RegionBindingsConstRef B,
1609 if (
const StringRegion *StrR=dyn_cast<StringRegion>(superR)) {
1612 QualType T = Ctx.getAsArrayType(StrR->getValueType())->getElementType();
1619 int64_t i = CI->getValue().getSExtValue();
1630 return svalBuilder.makeIntVal(c, T);
1635 if (isa<CodeTextRegion>(superR))
1651 dyn_cast_or_null<TypedValueRegion>(O.
getRegion())) {
1652 QualType baseT = baseR->getValueType();
1656 if (Ctx.getTypeSizeInChars(baseT) >= Ctx.getTypeSizeInChars(elemT)) {
1659 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1671 return getBindingForFieldOrElementCommon(B, R, R->
getElementType());
1674 SVal RegionStoreManager::getBindingForField(RegionBindingsConstRef B,
1682 return getBindingForFieldOrElementCommon(B, R, Ty);
1686 RegionStoreManager::getBindingForDerivedDefaultValue(RegionBindingsConstRef B,
1692 const SVal &val = D.getValue();
1694 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1697 return svalBuilder.makeZeroVal(Ty);
1708 llvm_unreachable(
"Unknown default value");
1714 SVal RegionStoreManager::getLazyBinding(
const SubRegion *LazyBindingRegion,
1715 RegionBindingsRef LazyBinding) {
1717 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(LazyBindingRegion))
1718 Result = getBindingForElement(LazyBinding, ER);
1720 Result = getBindingForField(LazyBinding,
1721 cast<FieldRegion>(LazyBindingRegion));
1744 RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
1752 Store lazyBindingStore =
nullptr;
1753 const SubRegion *lazyBindingRegion =
nullptr;
1754 std::tie(lazyBindingStore, lazyBindingRegion) = findLazyBinding(B, R, R);
1755 if (lazyBindingRegion)
1756 return getLazyBinding(lazyBindingRegion,
1757 getRegionBindings(lazyBindingStore));
1761 bool hasSymbolicIndex =
false;
1777 bool hasPartialLazyBinding =
false;
1782 if (
Optional<SVal> D = getBindingForDerivedDefaultValue(B, Base, R, Ty)) {
1784 hasPartialLazyBinding =
true;
1791 if (
const ElementRegion *ER = dyn_cast<ElementRegion>(Base)) {
1792 NonLoc index = ER->getIndex();
1794 hasSymbolicIndex =
true;
1803 if (isa<ElementRegion>(R)) {
1808 if (typedSuperR->getValueType()->isVectorType())
1817 if (hasSymbolicIndex)
1820 if (!hasPartialLazyBinding)
1825 return svalBuilder.getRegionValueSymbolVal(R);
1828 SVal RegionStoreManager::getBindingForObjCIvar(RegionBindingsConstRef B,
1839 return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
1845 return getBindingForLazySymbol(R);
1848 SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B,
1860 if (isa<StackArgumentsSpaceRegion>(MS))
1861 return svalBuilder.getRegionValueSymbolVal(R);
1878 if (isa<UnknownSpaceRegion>(MS))
1879 return svalBuilder.getRegionValueSymbolVal(R);
1881 if (isa<GlobalsSpaceRegion>(MS)) {
1888 if (isa<StaticGlobalSpaceRegion>(MS))
1889 return svalBuilder.makeZeroVal(T);
1891 if (
Optional<SVal> V = getBindingForDerivedDefaultValue(B, MS, R, T)) {
1893 return V.getValue();
1896 return svalBuilder.getRegionValueSymbolVal(R);
1904 return svalBuilder.getRegionValueSymbolVal(R);
1907 const RegionStoreManager::SValListTy &
1910 LazyBindingsMapTy::iterator I = LazyBindingsMap.find(LCV.
getCVData());
1911 if (I != LazyBindingsMap.end())
1918 RegionBindingsRef B = getRegionBindings(LCV.
getStore());
1922 const ClusterBindings *Cluster = B.lookup(LazyR->getBaseRegion());
1924 return (LazyBindingsMap[LCV.
getCVData()] = std::move(List));
1938 const SValListTy &InnerList = getInterestingValues(*InnerLCV);
1939 List.insert(List.end(), InnerList.begin(), InnerList.end());
1946 return (LazyBindingsMap[LCV.
getCVData()] = std::move(List));
1949 NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B,
1955 return svalBuilder.makeLazyCompoundVal(
StoreRef(B.asStore(), *
this), R);
1962 return CRD->getNumBases() == 0;
1966 SVal RegionStoreManager::getBindingForStruct(RegionBindingsConstRef B,
1972 return createLazyBinding(B, R);
1975 SVal RegionStoreManager::getBindingForArray(RegionBindingsConstRef B,
1977 assert(Ctx.getAsConstantArrayType(R->
getValueType()) &&
1978 "Only constant array types can have compound bindings.");
1980 return createLazyBinding(B, R);
1983 bool RegionStoreManager::includedInBindings(
Store store,
1985 RegionBindingsRef B = getRegionBindings(store);
1989 if (B.lookup(region))
1993 for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI) {
1994 const ClusterBindings &Cluster = RI.getData();
1995 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
1997 const SVal &D = CI.getData();
2013 if (
const MemRegion* R = LV->getRegion())
2014 return StoreRef(getRegionBindings(ST).removeBinding(R)
2016 .getRootWithoutRetain(),
2023 RegionStoreManager::bind(RegionBindingsConstRef B,
Loc L,
SVal V) {
2034 return bindArray(B, TR, V);
2036 return bindStruct(B, TR, V);
2038 return bindVector(B, TR, V);
2040 return bindAggregate(B, TR, V);
2046 QualType T = SR->getSymbol()->getType();
2050 R = GetElementZeroRegion(SR, T);
2054 RegionBindingsRef NewB = removeSubRegionBindings(B, cast<SubRegion>(R));
2059 RegionStoreManager::setImplicitDefaultValue(RegionBindingsConstRef B,
2065 V = svalBuilder.makeNull();
2067 V = svalBuilder.makeZeroVal(T);
2071 V = svalBuilder.makeZeroVal(Ctx.IntTy);
2086 RegionStoreManager::bindArray(RegionBindingsConstRef B,
2095 Size = CAT->getSize().getZExtValue();
2102 return bindAggregate(B, R, V);
2107 return bindAggregate(B, R, Init);
2117 RegionBindingsRef NewB(B);
2119 for (; Size.hasValue() ? i < Size.getValue() :
true ; ++i, ++VI) {
2124 const NonLoc &Idx = svalBuilder.makeArrayIndex(i);
2125 const ElementRegion *ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx);
2128 NewB = bindStruct(NewB, ER, *VI);
2130 NewB = bindArray(NewB, ER, *VI);
2138 if (!Size.hasValue() || i < Size.getValue())
2139 NewB = setImplicitDefaultValue(NewB, R, ElementTy);
2144 RegionBindingsRef RegionStoreManager::bindVector(RegionBindingsConstRef B,
2153 return bindAggregate(B, R, V);
2162 QualType ElemType = VT->getElementType();
2165 unsigned index = 0, numElements = VT->getNumElements();
2166 RegionBindingsRef NewB(B);
2168 for ( ; index != numElements ; ++index) {
2172 NonLoc Idx = svalBuilder.makeArrayIndex(index);
2173 const ElementRegion *ER = MRMgr.getElementRegion(ElemType, Idx, R, Ctx);
2176 NewB = bindArray(NewB, ER, *VI);
2178 NewB = bindStruct(NewB, ER, *VI);
2186 RegionStoreManager::tryBindSmallStruct(RegionBindingsConstRef B,
2192 if (
const CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(RD))
2193 if (Class->getNumBases() != 0 || Class->getNumVBases() != 0)
2196 for (
const auto *FD : RD->
fields()) {
2197 if (FD->isUnnamedBitfield())
2202 if (Fields.size() == SmallStructLimit)
2209 Fields.push_back(FD);
2212 RegionBindingsRef NewB = B;
2214 for (FieldVector::iterator I = Fields.begin(), E = Fields.end(); I != E; ++I){
2216 SVal V = getBindingForField(getRegionBindings(LCV.
getStore()), SourceFR);
2218 const FieldRegion *DestFR = MRMgr.getFieldRegion(*I, R);
2225 RegionBindingsRef RegionStoreManager::bindStruct(RegionBindingsConstRef B,
2228 if (!Features.supportsFields())
2237 if (!RD->isCompleteDefinition())
2245 return bindAggregate(B, R, V);
2248 return bindAggregate(B, R, V);
2260 RegionBindingsRef NewB(B);
2262 for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI) {
2268 if (FI->isUnnamedBitfield())
2272 const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
2275 NewB = bindArray(NewB, FR, *VI);
2277 NewB = bindStruct(NewB, FR, *VI);
2286 svalBuilder.makeIntVal(0,
false));
2293 RegionStoreManager::bindAggregate(RegionBindingsConstRef B,
2306 class removeDeadBindingsWorker :
2307 public ClusterAnalysis<removeDeadBindingsWorker> {
2313 removeDeadBindingsWorker(RegionStoreManager &rm,
2317 : ClusterAnalysis<removeDeadBindingsWorker>(rm, stateMgr, b),
2318 SymReaper(symReaper), CurrentLCtx(LCtx) {}
2321 void VisitAddedToCluster(
const MemRegion *baseR,
const ClusterBindings &C);
2322 void VisitCluster(
const MemRegion *baseR,
const ClusterBindings *C);
2323 using ClusterAnalysis<removeDeadBindingsWorker>::VisitCluster;
2325 using ClusterAnalysis::AddToWorkList;
2329 bool UpdatePostponed();
2330 void VisitBinding(
SVal V);
2334 bool removeDeadBindingsWorker::AddToWorkList(
const MemRegion *R) {
2336 return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
2339 void removeDeadBindingsWorker::VisitAddedToCluster(
const MemRegion *baseR,
2340 const ClusterBindings &C) {
2342 if (
const VarRegion *VR = dyn_cast<VarRegion>(baseR)) {
2343 if (SymReaper.isLive(VR))
2344 AddToWorkList(baseR, &C);
2349 if (
const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
2350 if (SymReaper.isLive(SR->getSymbol()))
2351 AddToWorkList(SR, &C);
2353 Postponed.push_back(SR);
2358 if (isa<NonStaticGlobalSpaceRegion>(baseR)) {
2359 AddToWorkList(baseR, &C);
2364 if (
const CXXThisRegion *TR = dyn_cast<CXXThisRegion>(baseR)) {
2366 cast<StackArgumentsSpaceRegion>(TR->getSuperRegion());
2369 (RegCtx == CurrentLCtx || RegCtx->isParentOf(CurrentLCtx)))
2370 AddToWorkList(TR, &C);
2374 void removeDeadBindingsWorker::VisitCluster(
const MemRegion *baseR,
2375 const ClusterBindings *C) {
2381 if (
const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(baseR))
2382 SymReaper.markLive(SymR->getSymbol());
2384 for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E; ++I) {
2386 SymReaper.markElementIndicesLive(I.getKey().getRegion());
2388 VisitBinding(I.getData());
2392 void removeDeadBindingsWorker::VisitBinding(
SVal V) {
2397 const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
2399 for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
2410 SymReaper.markLive(R);
2415 E = BR->referenced_vars_end();
2416 for ( ; I != E; ++I)
2425 SymReaper.markLive(*SI);
2428 bool removeDeadBindingsWorker::UpdatePostponed() {
2431 bool changed =
false;
2434 I = Postponed.begin(), E = Postponed.end() ; I != E ; ++I) {
2436 if (SymReaper.isLive(SR->getSymbol())) {
2437 changed |= AddToWorkList(SR);
2446 StoreRef RegionStoreManager::removeDeadBindings(
Store store,
2449 RegionBindingsRef B = getRegionBindings(store);
2450 removeDeadBindingsWorker W(*
this, StateMgr, B, SymReaper, LCtx);
2451 W.GenerateClusters();
2456 W.AddToWorkList(*I);
2459 do W.RunWorkList();
while (W.UpdatePostponed());
2464 for (RegionBindingsRef::iterator I = B.begin(), E = B.end(); I != E; ++I) {
2468 if (W.isVisited(Base))
2478 const ClusterBindings &Cluster = I.getData();
2479 for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
2481 SVal X = CI.getData();
2483 for (; SI != SE; ++SI)
2488 return StoreRef(B.asStore(), *
this);
2495 void RegionStoreManager::print(
Store store, raw_ostream &OS,
2496 const char* nl,
const char *sep) {
2497 RegionBindingsRef B = getRegionBindings(store);
2498 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.
static void getSymbolicOffsetFields(BindingKey K, FieldVector &Fields)
bool operator==(CanQual< T > x, CanQual< U > y)
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
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.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
virtual QualType getValueType() const =0
static bool isRecordEmpty(const RecordDecl *RD)
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
const RecordDecl * getParent() const
getParent - Returns the parent of this field declaration, which is the struct in which this field is ...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const MemRegion * getRegion() 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.
QualType getElementType() const
VarDecl - An instance of this class is created to represent a variable declaration or definition...
const T * getAs() const
Member-template getAs<specific type>'.
QualType getElementType() const
std::unique_ptr< StoreManager > CreateFieldsOnlyRegionStoreManager(ProgramStateManager &StMgr)
CXXThisRegion - Represents the region for the implicit 'this' parameter in a call to a C++ method...
const MemRegion * getSuperRegion() const
RecordDecl - Represents a struct/union/class.
llvm::ImmutableMap< BindingKey, SVal > ClusterBindings
SmallVector< const FieldDecl *, 8 > FieldVector
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
RecordDecl * getDefinition() const
getDefinition - Returns the RecordDecl that actually defines this struct/union/class.
field_range fields() const
const FieldDecl * getDecl() const
static bool canSymbolicate(QualType T)
bool isReferenceType() const
SValBuilder & getSValBuilder()
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
virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const
getExtent - Returns the size of the region in bytes.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
static bool isLocType(QualType T)
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)
llvm::ImmutableMap< const MemRegion *, ClusterBindings > RegionBindings
const LazyCompoundValData * getCVData() const
SymExpr::symbol_iterator symbol_end() const
bool isScalarType() const
QualType getValueType() const override
Represent a region's offset within the top level base region.
const MemSpaceRegion * getMemorySpace() const
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
std::unique_ptr< StoreManager > CreateRegionStoreManager(ProgramStateManager &StMgr)
const VarRegion * getCapturedRegion() 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.
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...
bool hasLocalStorage() const
hasLocalStorage - Returns true if a variable with function scope is a non-static local variable...
const FunctionProtoType * T
const T * castAs() const
Member-template castAs<specific type>.
bool isInSystemHeader() const
Returns true if the callee is known to be from a system header.
uint32_t getCodeUnit(size_t i) const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Represents a GCC generic vector type.
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 + ...)
bool isNull() const
Return true if this QualType doesn't point to a type yet.
__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 StackFrameContext * getStackFrame() const
const VarDecl * getDecl() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
virtual bool isBoundable() const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isVoidPointerType() const
bool isStructureOrClassType() const
bool scan(nonloc::LazyCompoundVal val)
llvm::BumpPtrAllocator & getAllocator()
const MemRegion * getAsRegion() const
static QualType getUnderlyingType(const SubRegion *R)
bool isSubRegionOf(const MemRegion *R) const override
Check if the region is a subregion of the given region.
ASTContext & getContext()
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
bool isAnyPointerType() const
A class responsible for cleaning up unused symbols.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
region_iterator region_end() const
bool isVectorType() const
Tells that a region's contents is not changed.
RegionRawOffset getAsArrayOffset() const
Compute the offset within the array. The array might also be a subobject.
__PTRDIFF_TYPE__ ptrdiff_t
A signed integer type that is the result of subtracting two pointers.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Dataflow Directional Tag Classes.
raw_ostream & operator<<(raw_ostream &Out, const CheckerBase &Checker)
Dump checker name to stream.
bool isZeroConstant() const
const void * getStore() const
const MemRegion * getRegion() const
const Expr * getInit() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
region_iterator region_begin() const
Represents symbolic expression.
Represents an abstract call to a function or method along a particular path.
ASTContext & getContext()
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...
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
SubRegion - A region that subsets another larger region.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
int64_t getOffset() const
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.
const TypedValueRegion * getRegion() const
virtual bool isSubRegionOf(const MemRegion *R) const
Check if the region is a subregion of the given region.
const MemRegion * getBaseRegion() const
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
SymExpr::symbol_iterator symbol_begin() 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
Represents the canonical version of C arrays with a specified constant size.
bool hasSymbolicOffset() const
bool isUnknownOrUndef() const
TypedRegion - An abstract class representing regions that are typed.
Iterator over symbols that the current symbol depends on.