;
48 enum{ Symbolic = 0x2 };
50llvm::PointerIntPair<const MemRegion *, 2>
P;
57assert(r &&
Base&&
"Must have known regions.");
58assert(getConcreteOffsetRegion() ==
Base&&
"Failed to store base region");
62 explicitBindingKey(
const MemRegion*r, uint64_t offset, Kind k)
63:
P(r, k),
Data(offset) {
64assert(r &&
"Must have known regions.");
65assert(getOffset() == offset &&
"Failed to store offset");
67isa<ObjCIvarRegion, CXXDerivedObjectRegion>(r)) &&
72 boolisDirect()
const{
return P.getInt() &
Direct; }
73 boolisDefault()
const{
return!isDirect(); }
74 boolhasSymbolicOffset()
const{
return P.getInt() & Symbolic; }
78assert(!hasSymbolicOffset());
82 const SubRegion*getConcreteOffsetRegion()
const{
83assert(hasSymbolicOffset());
88 if(hasSymbolicOffset())
93 voidProfile(llvm::FoldingSetNodeID& ID)
const{
94 ID.AddPointer(
P.getOpaqueValue());
100 bool operator<(
constBindingKey &
X)
const{
101 if(
P.getOpaqueValue() <
X.P.getOpaqueValue())
103 if(
P.getOpaqueValue() >
X.P.getOpaqueValue())
105 return Data<
X.Data;
109 return P.getOpaqueValue() ==
X.P.getOpaqueValue() &&
113LLVM_DUMP_METHOD
void dump()
const;
117BindingKey BindingKey::Make(
const MemRegion*R, Kind k) {
120 returnBindingKey(cast<SubRegion>(R), cast<SubRegion>(RO.
getRegion()), k);
126static inlineraw_ostream &
operator<<(raw_ostream &Out, BindingKey K) {
127Out <<
"\"kind\": \""<< (K.isDirect() ?
"Direct":
"Default")
128<<
"\", \"offset\": ";
130 if(!K.hasSymbolicOffset())
131Out << K.getOffset();
140#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 141voidBindingKey::dump()
const{ llvm::errs() << *
this; }
152typedefllvm::ImmutableMap<const MemRegion *, ClusterBindings>
156classRegionBindingsRef :
publicllvm::ImmutableMapRef<const MemRegion *,
158ClusterBindings::Factory *CBFactory;
172 typedefllvm::ImmutableMapRef<const MemRegion *, ClusterBindings>
175RegionBindingsRef(ClusterBindings::Factory &CBFactory,
176 constRegionBindings::TreeTy *
T,
177RegionBindings::TreeTy::Factory *F,
179: llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(
T, F),
180CBFactory(&CBFactory), IsMainAnalysis(IsMainAnalysis) {}
182RegionBindingsRef(
constParentTy &
P,
183ClusterBindings::Factory &CBFactory,
185: llvm::ImmutableMapRef<const MemRegion *, ClusterBindings>(
P),
186CBFactory(&CBFactory), IsMainAnalysis(IsMainAnalysis) {}
188RegionBindingsRef add(key_type_ref K, data_type_ref
D)
const{
189 returnRegionBindingsRef(
static_cast<constParentTy *
>(
this)->add(K,
D),
190*CBFactory, IsMainAnalysis);
193RegionBindingsRef remove(key_type_ref K)
const{
194 returnRegionBindingsRef(
static_cast<constParentTy *
>(
this)->remove(K),
195*CBFactory, IsMainAnalysis);
198RegionBindingsRef addBinding(BindingKey K,
SVal V)
const;
200RegionBindingsRef addBinding(
const MemRegion*R,
201BindingKey::Kind k,
SVal V)
const;
203 const SVal*lookup(BindingKey K)
const;
204 const SVal*lookup(
const MemRegion*R, BindingKey::Kind k)
const;
207RegionBindingsRef removeBinding(BindingKey K);
209RegionBindingsRef removeBinding(
const MemRegion*R,
212RegionBindingsRef removeBinding(
const MemRegion*R) {
213 returnremoveBinding(R, BindingKey::Direct).
214removeBinding(R, BindingKey::Default);
217std::optional<SVal> getDirectBinding(
const MemRegion*R)
const;
221std::optional<SVal> getDefaultBinding(
const MemRegion*R)
const;
224 StoreasStore()
const{
225llvm::PointerIntPair<Store, 1, bool> Ptr = {
226asImmutableMap().getRootWithoutRetain(), IsMainAnalysis};
227 return reinterpret_cast<Store>(Ptr.getOpaqueValue());
230 boolisMainAnalysis()
const{
231 returnIsMainAnalysis;
234 voidprintJson(raw_ostream &Out,
const char*NL =
"\n",
235 unsigned intSpace = 0,
boolIsDot =
false)
const{
236 using namespace llvm;
237DenseMap<const MemRegion *, std::string> StringifyCache;
238 autoToString = [&StringifyCache](
const MemRegion*R) {
239 auto[Place, Inserted] = StringifyCache.try_emplace(R);
241 returnPlace->second;
243raw_string_ostream OS(Res);
250std::pair<const MemRegion *, ImmutableMap<BindingKey, SVal>>;
251 usingBinding = std::pair<BindingKey, SVal>;
253 const autoMemSpaceBeforeRegionName = [&ToString](
constCluster *L,
255 if(isa<MemSpaceRegion>(L->first) && !isa<MemSpaceRegion>(R->first))
257 if(!isa<MemSpaceRegion>(L->first) && isa<MemSpaceRegion>(R->first))
259 returnToString(L->first) < ToString(R->first);
262 const autoSymbolicBeforeOffset = [&ToString](
constBindingKey &L,
263 constBindingKey &R) {
264 if(L.hasSymbolicOffset() && !R.hasSymbolicOffset())
266 if(!L.hasSymbolicOffset() && R.hasSymbolicOffset())
268 if(L.hasSymbolicOffset() && R.hasSymbolicOffset())
269 returnToString(L.getRegion()) < ToString(R.getRegion());
270 returnL.getOffset() < R.getOffset();
273 const autoDefaultBindingBeforeDirectBindings =
274[&SymbolicBeforeOffset](
constBinding *LPtr,
constBinding *RPtr) {
275 constBindingKey &L = LPtr->first;
276 constBindingKey &R = RPtr->first;
277 if(L.isDefault() && !R.isDefault())
279 if(!L.isDefault() && R.isDefault())
281assert(L.isDefault() == R.isDefault());
282 returnSymbolicBeforeOffset(L, R);
285 const autoAddrOf = [](
const auto&Item) {
return&Item; };
287std::vector<const Cluster *> SortedClusters;
288SortedClusters.reserve(std::distance(begin(), end()));
289append_range(SortedClusters, map_range(*
this, AddrOf));
290llvm::sort(SortedClusters, MemSpaceBeforeRegionName);
292 for(
auto[Idx,
C] : llvm::enumerate(SortedClusters)) {
293 const auto&[BaseRegion,
Bindings] = *
C;
294Indent(Out, Space, IsDot)
295<<
"{ \"cluster\": \""<< BaseRegion <<
"\", \"pointer\": \"" 296<< (
const void*)BaseRegion <<
"\", \"items\": ["<< NL;
298std::vector<const Binding *> SortedBindings;
300append_range(SortedBindings, map_range(
Bindings, AddrOf));
301llvm::sort(SortedBindings, DefaultBindingBeforeDirectBindings);
304 for(
auto[Idx, B] : llvm::enumerate(SortedBindings)) {
305 const auto&[Key,
Value] = *B;
306Indent(Out, Space, IsDot) <<
"{ "<< Key <<
", \"value\": ";
307 Value.printJson(Out,
true);
309 if(Idx != SortedBindings.size() - 1)
314Indent(Out, Space, IsDot) <<
"]}";
315 if(Idx != SortedClusters.size() - 1)
321LLVM_DUMP_METHOD
void dump()
const{ printJson(llvm::errs()); }
328RegionBindingsRef::getDirectBinding(
const MemRegion*R)
const{
329 const SVal*
V= lookup(R, BindingKey::Direct);
330 return V? std::optional<SVal>(*
V) : std::nullopt;
334RegionBindingsRef::getDefaultBinding(
const MemRegion*R)
const{
335 const SVal*
V= lookup(R, BindingKey::Default);
336 return V? std::optional<SVal>(*
V) :
std::nullopt;
339RegionBindingsRef RegionBindingsRef::addBinding(BindingKey K,
SVal V)
const{
344(ExistingCluster ? *ExistingCluster : CBFactory->getEmptyMap());
347 returnadd(
Base, NewCluster);
351RegionBindingsRef RegionBindingsRef::addBinding(
const MemRegion*R,
354 returnaddBinding(BindingKey::Make(R, k),
V);
357const SVal*RegionBindingsRef::lookup(BindingKey K)
const{
361 returnCluster->lookup(K);
365BindingKey::Kind k)
const{
366 returnlookup(BindingKey::Make(R, k));
369RegionBindingsRef RegionBindingsRef::removeBinding(BindingKey K) {
376 if(NewCluster.isEmpty())
378 returnadd(
Base, NewCluster);
381RegionBindingsRef RegionBindingsRef::removeBinding(
const MemRegion*R,
383 returnremoveBinding(BindingKey::Make(R, k));
391classInvalidateRegionsWorker;
395RegionBindings::Factory RBFactory;
396 mutableClusterBindings::Factory CBFactory;
398 typedefstd::vector<SVal> SValListTy;
401SValListTy> LazyBindingsMapTy;
402LazyBindingsMapTy LazyBindingsMap;
412 unsignedSmallStructLimit;
422 unsignedSmallArrayLimit;
426 voidpopulateWorkList(InvalidateRegionsWorker &W,
428InvalidatedRegions *TopLevelRegions);
433CBFactory(mgr.getAllocator()), SmallStructLimit(0), SmallArrayLimit(0) {
436SmallStructLimit = Options.RegionStoreSmallStructLimit;
437SmallArrayLimit = Options.RegionStoreSmallArrayLimit;
457 boolIsMainAnalysis =
false;
458 if(
const auto*FD = dyn_cast<FunctionDecl>(InitLoc->
getDecl()))
459IsMainAnalysis = FD->isMain() && !Ctx.
getLangOpts().CPlusPlus;
461RegionBindingsRef::ParentTy(RBFactory.getEmptyMap(), RBFactory),
462CBFactory, IsMainAnalysis).asStore(), *
this);
472InvalidatedRegions *Invalidated);
478InvalidatedRegions *Invalidated,
479InvalidatedRegions *InvalidatedTopLevel)
override;
499 return StoreRef(bind(getRegionBindings(store), LV,
V).asStore(), *
this);
508RegionBindingsRef B = getRegionBindings(store);
511assert(!(B.getDefaultBinding(R) || B.getDirectBinding(R)) &&
512 "Double initialization!");
513B = B.addBinding(BindingKey::Make(R, BindingKey::Default),
V);
514 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *
this);
529 if(
const auto*BR = dyn_cast<CXXBaseObjectRegion>(R))
530 if(BR->getDecl()->isEmpty())
533RegionBindingsRef B = getRegionBindings(store);
535B = removeSubRegionBindings(B, cast<SubRegion>(R));
536B = B.addBinding(BindingKey::Make(R, BindingKey::Default),
V);
537 return StoreRef(B.asImmutableMap().getRootWithoutRetain(), *
this);
550std::optional<RegionBindingsRef>
562std::optional<RegionBindingsRef>
582getRegionBindings(store).manualRetain();
589getRegionBindings(store).manualRelease();
617RegionBindingsRef B = getRegionBindings(S);
641RegionBindingsRef LazyBinding);
666std::pair<Store, const SubRegion *>
695RegionBindingsRef getRegionBindings(
Storestore)
const{
696llvm::PointerIntPair<Store, 1, bool> Ptr;
697Ptr.setFromOpaqueValue(
const_cast<void*
>(store));
698 returnRegionBindingsRef(
700 static_cast<constRegionBindings::TreeTy *
>(Ptr.getPointer()),
701RBFactory.getTreeFactory(),
705 void printJson(raw_ostream &Out,
StoreS,
const char*NL =
"\n",
706 unsigned intSpace = 0,
boolIsDot =
false)
const override;
709RegionBindingsRef B = getRegionBindings(store);
710 for(
const auto&[Region, Cluster] : B) {
711 for(
const auto&[Key,
Value] : Cluster) {
714 if(
const SubRegion*R = dyn_cast<SubRegion>(Key.getRegion())) {
716 if(!f.HandleBinding(*
this, store, R,
Value))
730std::unique_ptr<StoreManager>
732 returnstd::make_unique<RegionStoreManager>(StMgr);
742enumGlobalsFilterKind {
751template<
typenameDERIVED>
752classClusterAnalysis {
754 typedefllvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
755 typedef const MemRegion* WorkListElement;
762RegionStoreManager &RM;
783RegionBindingsRef
b)
784: RM(rm), Ctx(StateMgr.getContext()),
785svalBuilder(StateMgr.getSValBuilder()), B(
std::move(
b)) {}
787RegionBindingsRef getRegionBindings()
const{
returnB; }
790 return Visited.count(getCluster(R));
793 voidGenerateClusters() {
795 for(RegionBindingsRef::iterator RI = B.begin(), RE = B.end();
800assert(!Cluster.isEmpty() &&
"Empty clusters should be removed");
801 static_cast<DERIVED*
>(
this)->VisitAddedToCluster(
Base, Cluster);
805 if(
static_cast<DERIVED*
>(
this)->includeEntireMemorySpace(
Base))
806AddToWorkList(WorkListElement(
Base), &Cluster);
817 boolAddToWorkList(
const MemRegion*R) {
818 return static_cast<DERIVED*
>(
this)->AddToWorkList(R);
822 while(!WL.empty()) {
823WorkListElement
E= WL.pop_back_val();
826 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR, getCluster(BaseR));
835 static_cast<DERIVED*
>(
this)->VisitCluster(BaseR,
C);
844boolRegionStoreManager::scanReachableSymbols(
StoreS,
const MemRegion*R,
846assert(R == R->
getBaseRegion() &&
"Should only be called for base regions");
847RegionBindingsRef B = getRegionBindings(S);
853 for(ClusterBindings::iterator RI = Cluster->begin(), RE = Cluster->end();
855 if(!Callbacks.
scan(RI.getData()))
869assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
875 if(
const FieldRegion*FR = dyn_cast<FieldRegion>(R))
877Fields.push_back(FR->getDecl());
879R = cast<SubRegion>(R)->getSuperRegion();
884assert(K.hasSymbolicOffset() &&
"Not implemented for concrete offset keys");
892 ptrdiff_tDelta = FieldsInBindingKey.size() - Fields.size();
894 returnstd::equal(FieldsInBindingKey.begin() + Delta,
895FieldsInBindingKey.end(),
898 returnstd::equal(FieldsInBindingKey.begin(), FieldsInBindingKey.end(),
899Fields.begin() - Delta);
915 boolIncludeAllDefaultBindings) {
917 if(TopKey.hasSymbolicOffset()) {
919Top = TopKey.getConcreteOffsetRegion();
920TopKey = BindingKey::Make(Top, BindingKey::Default);
924uint64_t Length = UINT64_MAX;
926 if(std::optional<nonloc::ConcreteInt> ExtentCI =
928 constllvm::APSInt &ExtentInt = ExtentCI->getValue();
929assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned());
932}
else if(
const FieldRegion*FR = dyn_cast<FieldRegion>(Top)) {
933 if(FR->getDecl()->isBitField())
934Length = FR->getDecl()->getBitWidthValue();
937 for(
const auto&StoreEntry : Cluster) {
938BindingKey NextKey = StoreEntry.first;
939 if(NextKey.getRegion() == TopKey.getRegion()) {
945 if(NextKey.getOffset() > TopKey.getOffset() &&
946NextKey.getOffset() - TopKey.getOffset() < Length) {
951}
else if(NextKey.getOffset() == TopKey.getOffset()) {
958 if(IncludeAllDefaultBindings || NextKey.isDirect())
962}
else if(NextKey.hasSymbolicOffset()) {
968 if(IncludeAllDefaultBindings || NextKey.isDirect())
971}
else if(
const SubRegion*BaseSR = dyn_cast<SubRegion>(
Base)) {
974 if(BaseSR->isSubRegionOf(Top))
985 const SubRegion*Top,
boolIncludeAllDefaultBindings) {
987BindingKey::Make(Top, BindingKey::Default),
988IncludeAllDefaultBindings);
994BindingKey TopKey = BindingKey::Make(Top, BindingKey::Default);
997 if(Top == ClusterHead) {
999 returnB.remove(Top);
1006 if(TopKey.hasSymbolicOffset()) {
1007 const SubRegion*Concrete = TopKey.getConcreteOffsetRegion();
1008 returnB.addBinding(Concrete, BindingKey::Default,
UnknownVal());
1018 for(BindingKey Key : llvm::make_first_range(
Bindings))
1019Result = Result.remove(Key);
1025 if(TopKey.hasSymbolicOffset()) {
1026 const SubRegion*Concrete = TopKey.getConcreteOffsetRegion();
1027Result = Result.
add(BindingKey::Make(Concrete, BindingKey::Default),
1031 if(Result.isEmpty())
1032 returnB.remove(ClusterHead);
1033 returnB.add(ClusterHead, Result.asImmutableMap());
1037classInvalidateRegionsWorker :
publicClusterAnalysis<InvalidateRegionsWorker>
1045GlobalsFilterKind GlobalsFilter;
1048RegionBindingsRef
b,
const Stmt*S,
unsignedcount,
1052GlobalsFilterKind GFK)
1053: ClusterAnalysis<InvalidateRegionsWorker>(rm, stateMgr,
b), S(S),
1054Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r),
1055GlobalsFilter(GFK) {}
1058 voidVisitBinding(
SVal V);
1060 usingClusterAnalysis::AddToWorkList;
1062 boolAddToWorkList(
const MemRegion*R);
1070 boolisInitiallyIncludedGlobalRegion(
const MemRegion*R);
1074boolInvalidateRegionsWorker::AddToWorkList(
const MemRegion*R) {
1075 booldoNotInvalidateSuperRegion = ITraits.hasTrait(
1078 returnAddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
1081voidInvalidateRegionsWorker::VisitBinding(
SVal V) {
1086 if(
const MemRegion*R =
V.getAsRegion()) {
1092 if(std::optional<nonloc::LazyCompoundVal> LCS =
1097 for(
SVal V: RM.getInterestingValues(*LCS))
1098 if(!isa<nonloc::LazyCompoundVal>(
V))
1105voidInvalidateRegionsWorker::VisitCluster(
const MemRegion*baseR,
1108 boolPreserveRegionsContents =
1109ITraits.hasTrait(baseR,
1113 for(
SValVal : llvm::make_second_range(*
C))
1117 if(!PreserveRegionsContents)
1118B = B.remove(baseR);
1121 if(
const auto*TO = dyn_cast<TypedValueRegion>(baseR)) {
1122 if(
const auto*RD = TO->getValueType()->getAsCXXRecordDecl()) {
1127 if(RD->isLambda() && RD->getLambdaCallOperator()->getBody()) {
1128 using namespaceast_matchers;
1130 const char*DeclBind =
"DeclBind";
1132to(
varDecl(hasStaticStorageDuration()).bind(DeclBind)))));
1134 match(RefToStatic, *RD->getLambdaCallOperator()->getBody(),
1135RD->getASTContext());
1138 auto*VD = Match.getNodeAs<
VarDecl>(DeclBind);
1140RM.getRegionManager().getVarRegion(VD, LCtx);
1141AddToWorkList(ToInvalidate);
1150 for(
autoVar : BR->referenced_vars()) {
1151 const VarRegion*VR = Var.getCapturedRegion();
1163 if(std::optional<Loc> L =
V.getAs<
Loc>()) {
1174IS.insert(SR->getSymbol());
1177 if(PreserveRegionsContents)
1182Regions->push_back(baseR);
1184 if(isa<AllocaRegion, SymbolicRegion>(baseR)) {
1189B = B.addBinding(baseR, BindingKey::Default,
V);
1199 if(isInitiallyIncludedGlobalRegion(baseR)) {
1211B = B.addBinding(baseR, BindingKey::Default,
V);
1216 booldoNotInvalidateSuperRegion = ITraits.hasTrait(
1220 if(doNotInvalidateSuperRegion) {
1223std::optional<uint64_t> NumElements;
1227NumElements = CAT->getZExtSize();
1229 gotoconjure_default;
1230 QualTypeElementTy = AT->getElementType();
1238AddToWorkList(SuperR);
1239 gotoconjure_default;
1243 uint64_tUpperOffset = LowerOffset + *NumElements * ElemSize;
1244 boolUpperOverflow = UpperOffset < LowerOffset;
1249 gotoconjure_default;
1253 gotoconjure_default;
1255 for(
const auto&[BK,
V] : *
C) {
1256std::optional<uint64_t> ROffset =
1257BK.hasSymbolicOffset() ? std::optional<uint64_t>() : BK.getOffset();
1262((*ROffset >= LowerOffset && *ROffset < UpperOffset) ||
1264(*ROffset >= LowerOffset || *ROffset < UpperOffset)) ||
1265(LowerOffset == UpperOffset && *ROffset == LowerOffset))) {
1266B = B.removeBinding(BK);
1270 if(isa_and_nonnull<SymbolicRegion>(R))
1278baseR, S, LCtx, AT->getElementType(), Count);
1279B = B.addBinding(baseR, BindingKey::Default,
V);
1286B = B.addBinding(baseR, BindingKey::Direct,
V);
1289boolInvalidateRegionsWorker::isInitiallyIncludedGlobalRegion(
1291 switch(GlobalsFilter) {
1294 caseGFK_SystemOnly:
1300llvm_unreachable(
"unknown globals filter");
1303boolInvalidateRegionsWorker::includeEntireMemorySpace(
const MemRegion*
Base) {
1304 if(isInitiallyIncludedGlobalRegion(
Base))
1308 returnITraits.hasTrait(MemSpace,
1312RegionBindingsRef RegionStoreManager::invalidateGlobalRegion(
1315InvalidatedRegions *Invalidated) {
1321Ctx.
IntTy, Count);
1323B = B.removeBinding(GS)
1324.addBinding(BindingKey::Make(GS, BindingKey::Default),
V);
1329Invalidated->push_back(GS);
1334voidRegionStoreManager::populateWorkList(InvalidateRegionsWorker &W,
1336InvalidatedRegions *TopLevelRegions) {
1337 for(
SVal V: Values) {
1339 for(
SValS : getInterestingValues(*LCS))
1340 if(
const MemRegion*R = S.getAsRegion())
1346 if(
const MemRegion*R =
V.getAsRegion()) {
1347 if(TopLevelRegions)
1348TopLevelRegions->push_back(R);
1355StoreRefRegionStoreManager::invalidateRegions(
1359InvalidatedRegions *TopLevelRegions, InvalidatedRegions *Invalidated) {
1360GlobalsFilterKind GlobalsFilter;
1362 if(
Call->isInSystemHeader())
1363GlobalsFilter = GFK_SystemOnly;
1365GlobalsFilter = GFK_All;
1367GlobalsFilter = GFK_None;
1370RegionBindingsRef B = getRegionBindings(store);
1371InvalidateRegionsWorker W(*
this, StateMgr, B, S, Count, LCtx, IS, ITraits,
1372Invalidated, GlobalsFilter);
1375W.GenerateClusters();
1378populateWorkList(W, Values, TopLevelRegions);
1383B = W.getRegionBindings();
1389 switch(GlobalsFilter) {
1391B = invalidateGlobalRegion(MemRegion::GlobalInternalSpaceRegionKind, S,
1392Count, LCtx, B, Invalidated);
1394 caseGFK_SystemOnly:
1395B = invalidateGlobalRegion(MemRegion::GlobalSystemSpaceRegionKind, S, Count,
1396LCtx, B, Invalidated);
1402 return StoreRef(B.asStore(), *
this);
1416 if(isa<loc::ConcreteInt>(Array))
1419 if(!isa<loc::MemRegionVal>(Array))
1433assert(!isa<UnknownVal>(L) &&
"location unknown");
1434assert(!isa<UndefinedVal>(L) &&
"location undefined");
1451 if(isa<BlockDataRegion>(MR)) {
1457 if(
const auto*TVR = dyn_cast<TypedValueRegion>(MR))
1458 T= TVR->getValueType();
1459 else if(
const auto*TR = dyn_cast<TypedRegion>(MR))
1461 else if(
const auto*SR = dyn_cast<SymbolicRegion>(MR))
1462 T= SR->getPointeeStaticType();
1464assert(!
T.isNull() &&
"Unable to auto-detect binding type!");
1465assert(!
T->
isVoidType() &&
"Attempting to dereference a void pointer!");
1467 if(!isa<TypedValueRegion>(MR))
1468MR = GetElementZeroRegion(cast<SubRegion>(MR),
T);
1489 returngetBindingForStruct(B, R);
1493 returncreateLazyBinding(B, R);
1497 returngetBindingForArray(B, R);
1506 if(
const FieldRegion* FR = dyn_cast<FieldRegion>(R))
1509 if(
const ElementRegion* ER = dyn_cast<ElementRegion>(R)) {
1528 if(
const VarRegion*VR = dyn_cast<VarRegion>(R)) {
1538 const SVal*
V= B.lookup(R, BindingKey::Direct);
1562RegionTy = TVR->getValueType();
1565RegionTy = SR->getSymbol()->getType();
1577staticstd::optional<nonloc::LazyCompoundVal>
1579 const SubRegion*R,
boolAllowSubregionBindings) {
1580std::optional<SVal>
V= B.getDefaultBinding(R);
1582 returnstd::nullopt;
1584std::optional<nonloc::LazyCompoundVal> LCV =
1587 returnstd::nullopt;
1592 if(!RegionTy.
isNull() &&
1594 QualTypeSourceRegionTy = LCV->getRegion()->getValueType();
1596 returnstd::nullopt;
1599 if(!AllowSubregionBindings) {
1606 returnstd::nullopt;
1612std::pair<Store, const SubRegion *>
1616 if(originalRegion != R) {
1617 if(std::optional<nonloc::LazyCompoundVal>
V=
1619 returnstd::make_pair(
V->getStore(),
V->getRegion());
1622 typedefstd::pair<Store, const SubRegion *> StoreRegionPair;
1623StoreRegionPair Result = StoreRegionPair();
1625 if(
const ElementRegion*ER = dyn_cast<ElementRegion>(R)) {
1626Result = findLazyBinding(B, cast<SubRegion>(ER->getSuperRegion()),
1630Result.second = MRMgr.getElementRegionWithSuper(ER, Result.second);
1632}
else if(
const FieldRegion*FR = dyn_cast<FieldRegion>(R)) {
1633Result = findLazyBinding(B, cast<SubRegion>(FR->getSuperRegion()),
1637Result.second = MRMgr.getFieldRegionWithSuper(FR, Result.second);
1640dyn_cast<CXXBaseObjectRegion>(R)) {
1643Result = findLazyBinding(B, cast<SubRegion>(BaseReg->getSuperRegion()),
1647Result.second = MRMgr.getCXXBaseObjectRegionWithSuper(BaseReg,
1661assert(CAT &&
"ConstantArrayType should not be null");
1666}
while((CAT = dyn_cast<ConstantArrayType>(CAT->
getElementType())));
1684staticstd::pair<SmallVector<SVal, 2>,
const MemRegion*>
1686assert(ER &&
"ConstantArrayType should not be null");
1690SValOffsets.push_back(ER->
getIndex());
1692ER = dyn_cast<ElementRegion>(
Base);
1694 return{SValOffsets,
Base};
1718staticstd::optional<SVal>
1739DstOffsets.resize(SrcOffsets.size());
1740 autoExtentIt = ArrayExtents.begin();
1741 autoOffsetIt = DstOffsets.begin();
1743 for(
SVal V: llvm::reverse(SrcOffsets)) {
1746 constllvm::APSInt &Offset = CI->getValue();
1747 if(Offset.isNegative() || Offset.uge(*(ExtentIt++)))
1750*(OffsetIt++) = Offset.getZExtValue();
1758 returnstd::nullopt;
1761std::optional<SVal> RegionStoreManager::getConstantValFromConstArrayInitializer(
1763assert(R &&
"ElementRegion should not be null");
1771 returnstd::nullopt;
1773assert(!SValOffsets.empty() &&
"getElementRegionOffsets guarantees the " 1774 "offsets vector is not empty.");
1782 returnstd::nullopt;
1797 returnstd::nullopt;
1803 returnstd::nullopt;
1814 if(SValOffsets.size() != Extents.size())
1815 returnstd::nullopt;
1819SValOffsets, Extents, ConcreteOffsets))
1825 if(
const auto*ILE = dyn_cast<InitListExpr>(
Init))
1826 returngetSValFromInitListExpr(ILE, ConcreteOffsets, R->
getElementType());
1831 if(
const auto*SL = dyn_cast<StringLiteral>(
Init))
1832 returngetSValFromStringLiteral(SL, ConcreteOffsets.front(),
1837 returnstd::nullopt;
1857std::optional<SVal> RegionStoreManager::getSValFromInitListExpr(
1860assert(ILE &&
"InitListExpr should not be null");
1862 for(uint64_t Offset : Offsets) {
1869 if(
const auto*SL = dyn_cast<StringLiteral>(ILE->
getInit(0)))
1870 returngetSValFromStringLiteral(SL, Offset, ElemT);
1879 const auto*IL = dyn_cast<InitListExpr>(
E);
1893 returnstd::nullopt;
1924assert(SL &&
"StringLiteral should not be null");
1929 returnsvalBuilder.
makeIntVal(Code, ElemT);
1940 if(
conststd::optional<SVal> &ParentValue =
1941B.getDirectBinding(BaseRegion)) {
1942 if(
SymbolRefParentValueAsSym = ParentValue->getAsSymbol())
1945 if(ParentValue->isUndef())
1954 returnstd::nullopt;
1960 if(
conststd::optional<SVal> &
V= B.getDirectBinding(R))
1966 if(
const StringRegion*StrR = dyn_cast<StringRegion>(superR)) {
1974 constllvm::APSInt &Idx = CI->getValue();
1978 returngetSValFromStringLiteral(SL, Idx.getZExtValue(),
T);
1980}
else if(isa<ElementRegion, VarRegion>(superR)) {
1981 if(std::optional<SVal>
V= getConstantValFromConstArrayInitializer(B, R))
1986 if(isa<CodeTextRegion>(superR))
2005 returngetBindingForFieldOrElementCommon(B, R, R->
getElementType());
2012 if(
conststd::optional<SVal> &
V= B.getDirectBinding(R))
2019 if(
const auto*VR = dyn_cast<VarRegion>(superR)) {
2029 if(
const auto*InitList = dyn_cast<InitListExpr>(
Init)) {
2030 if(Index < InitList->getNumInits()) {
2031 if(
const Expr*FieldInit = InitList->getInit(Index))
2060 returngetBindingForFieldOrElementCommon(B, R, Ty);
2063std::optional<SVal> RegionStoreManager::getBindingForDerivedDefaultValue(
2067 if(
conststd::optional<SVal> &
D= B.getDefaultBinding(superR)) {
2080 if(isa<nonloc::LazyCompoundVal, nonloc::CompoundVal>(val))
2083llvm_unreachable(
"Unknown default value");
2086 returnstd::nullopt;
2089SValRegionStoreManager::getLazyBinding(
const SubRegion*LazyBindingRegion,
2090RegionBindingsRef LazyBinding) {
2092 if(
const ElementRegion*ER = dyn_cast<ElementRegion>(LazyBindingRegion))
2093Result = getBindingForElement(LazyBinding, ER);
2095Result = getBindingForField(LazyBinding,
2096cast<FieldRegion>(LazyBindingRegion));
2112 if(Result.isUndef())
2127 StorelazyBindingStore =
nullptr;
2128 const SubRegion*lazyBindingRegion =
nullptr;
2129std::tie(lazyBindingStore, lazyBindingRegion) = findLazyBinding(B, R, R);
2130 if(lazyBindingRegion)
2131 returngetLazyBinding(lazyBindingRegion,
2132getRegionBindings(lazyBindingStore));
2136 boolhasSymbolicIndex =
false;
2152 boolhasPartialLazyBinding =
false;
2157 if(std::optional<SVal>
D=
2158getBindingForDerivedDefaultValue(B,
Base, R, Ty)) {
2160hasPartialLazyBinding =
true;
2168 NonLocindex = ER->getIndex();
2170hasSymbolicIndex =
true;
2175SR = dyn_cast<SubRegion>(
Base);
2179 if(isa<ElementRegion>(R)) {
2184 if(typedSuperR->getValueType()->isVectorType())
2193 if(hasSymbolicIndex)
2199 if(!hasPartialLazyBinding && !isa<BlockDataRegion>(R->
getBaseRegion())) {
2200 if(
conststd::optional<SVal> &
V= B.getDefaultBinding(R))
2213 if(
conststd::optional<SVal> &
V= B.getDirectBinding(R))
2219 if(
conststd::optional<SVal> &
V= B.getDefaultBinding(superR)) {
2220 if(
SymbolRefparentSym =
V->getAsSymbol())
2227 returngetBindingForLazySymbol(R);
2234 if(std::optional<SVal>
V= B.getDirectBinding(R))
2237 if(std::optional<SVal>
V= B.getDefaultBinding(R))
2245 if(isa<StackArgumentsSpaceRegion>(MS))
2263 if(isa<UnknownSpaceRegion>(MS))
2266 if(isa<GlobalsSpaceRegion>(MS)) {
2270 if(B.isMainAnalysis())
2279 if(isa<StaticGlobalSpaceRegion>(MS))
2282 if(std::optional<SVal>
V= getBindingForDerivedDefaultValue(B, MS, R,
T)) {
2298constRegionStoreManager::SValListTy &
2301LazyBindingsMapTy::iterator I = LazyBindingsMap.find(LCV.
getCVData());
2302 if(I != LazyBindingsMap.end())
2309RegionBindingsRef B = getRegionBindings(LCV.
getStore());
2315 return(LazyBindingsMap[LCV.
getCVData()] = std::move(List));
2321 if(
V.isUnknownOrUndef() ||
V.isConstant())
2325 constSValListTy &InnerList = getInterestingValues(*InnerLCV);
2326List.insert(List.end(), InnerList.begin(), InnerList.end());
2329List.push_back(
V);
2332 return(LazyBindingsMap[LCV.
getCVData()] = std::move(List));
2337 if(std::optional<nonloc::LazyCompoundVal>
V=
2357 if(std::optional<SVal> Val = getUniqueDefaultBinding(B, R))
2359 returncreateLazyBinding(B, R);
2365 "Only constant array types can have compound bindings.");
2367 returncreateLazyBinding(B, R);
2370boolRegionStoreManager::includedInBindings(
Storestore,
2372RegionBindingsRef B = getRegionBindings(store);
2376 if(B.lookup(region))
2380 for(RegionBindingsRef::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI) {
2382 for(ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
2384 SVal D= CI.getData();
2400 if(
const MemRegion* R = LV->getRegion())
2401 return StoreRef(getRegionBindings(ST).removeBinding(R)
2403.getRootWithoutRetain(),
2416 const MemRegion*R = MemRegVal->getRegion();
2422 returnbindArray(B, TR,
V);
2424 returnbindStruct(B, TR,
V);
2426 returnbindVector(B, TR,
V);
2428 returnbindAggregate(B, TR,
V);
2433 if(
const auto*SymReg = dyn_cast<SymbolicRegion>(R)) {
2434 QualTypeTy = SymReg->getPointeeStaticType();
2436Ty = StateMgr.getContext().CharTy;
2437R = GetElementZeroRegion(SymReg, Ty);
2440assert((!isa<CXXThisRegion>(R) || !B.lookup(R)) &&
2441 "'this' pointer is not an l-value and is not assignable");
2444RegionBindingsRef NewB = removeSubRegionBindings(B, cast<SubRegion>(R));
2447 autoKeyKind = isa<nonloc::LazyCompoundVal>(
V) ? BindingKey::Default
2448: BindingKey::Direct;
2449 returnNewB.addBinding(BindingKey::Make(R, KeyKind),
V);
2476 returnB.addBinding(R, BindingKey::Default,
V);
2479std::optional<RegionBindingsRef> RegionStoreManager::tryBindSmallArray(
2483 autoCAT = dyn_cast<ConstantArrayType>(AT);
2487 returnstd::nullopt;
2491 returnstd::nullopt;
2495 if(ArrSize > SmallArrayLimit)
2496 returnstd::nullopt;
2498RegionBindingsRef NewB = B;
2500 for(uint64_t i = 0; i < ArrSize; ++i) {
2503MRMgr.getElementRegion(Ty, Idx, LCV.
getRegion(), Ctx);
2504 SVal V= getBindingForElement(getRegionBindings(LCV.
getStore()), SrcER);
2506 const ElementRegion*DstER = MRMgr.getElementRegion(Ty, Idx, R, Ctx);
2520std::optional<uint64_t>
Size;
2530 returnbindAggregate(B, R,
V);
2534 if(std::optional<nonloc::LazyCompoundVal> LCV =
2536 if(std::optional<RegionBindingsRef> NewB =
2537tryBindSmallArray(B, R, AT, *LCV))
2540 returnbindAggregate(B, R,
Init);
2543 if(
Init.isUnknown())
2551RegionBindingsRef NewB(B);
2553 for(;
Size? i < *
Size:
true; ++i, ++VI) {
2559 const ElementRegion*ER = MRMgr.getElementRegion(ElementTy, Idx, R, Ctx);
2562NewB = bindStruct(NewB, ER, *VI);
2564NewB = bindArray(NewB, ER, *VI);
2572 if(!Size || i < *Size)
2573NewB = setImplicitDefaultValue(NewB, R, ElementTy);
2585 if(isa<nonloc::LazyCompoundVal, nonloc::SymbolVal>(
V))
2586 returnbindAggregate(B, R,
V);
2591 if(!isa<nonloc::CompoundVal>(
V)) {
2599RegionBindingsRef NewB(B);
2601 for( ; index != numElements ; ++index) {
2606 const ElementRegion*ER = MRMgr.getElementRegion(ElemType, Idx, R, Ctx);
2609NewB = bindArray(NewB, ER, *VI);
2611NewB = bindStruct(NewB, ER, *VI);
2622 returnstd::nullopt;
2624 const auto*Cluster = B.lookup(R);
2625 if(!Cluster || !llvm::hasSingleElement(*Cluster))
2626 returnstd::nullopt;
2628 const auto[Key,
Value] = *Cluster->begin();
2629 returnKey.isDirect() ? std::optional<SVal>{} :
Value;
2635 returngetUniqueDefaultBinding(B, LCV.
getRegion());
2638std::optional<RegionBindingsRef> RegionStoreManager::tryBindSmallStruct(
2655 if(std::optional<SVal> Val = getUniqueDefaultBinding(LCV)) {
2656 returnB.addBinding(BindingKey::Make(R, BindingKey::Default), Val.value());
2661 if(
const CXXRecordDecl*Class = dyn_cast<CXXRecordDecl>(RD))
2662 if(
Class->getNumBases() != 0 ||
Class->getNumVBases() != 0)
2663 returnstd::nullopt;
2665 for(
const auto*FD : RD->
fields()) {
2671 if(Fields.size() == SmallStructLimit)
2672 returnstd::nullopt;
2682 returnstd::nullopt;
2684Fields.push_back(FD);
2687RegionBindingsRef NewB = B;
2689 for(
const FieldDecl*Field : Fields) {
2691 SVal V= getBindingForField(getRegionBindings(LCV.
getStore()), SourceFR);
2693 const FieldRegion*DestFR = MRMgr.getFieldRegion(Field, R);
2709 if(!RD->isCompleteDefinition())
2713 if(std::optional<nonloc::LazyCompoundVal> LCV =
2715 if(std::optional<RegionBindingsRef> NewB =
2716tryBindSmallStruct(B, R, RD, *LCV))
2718 returnbindAggregate(B, R,
V);
2720 if(isa<nonloc::SymbolVal>(
V))
2721 returnbindAggregate(B, R,
V);
2726 if(
V.isUnknown() || !isa<nonloc::CompoundVal>(
V))
2748RegionBindingsRef NewB(B);
2752 if(
const auto*CRD = dyn_cast<CXXRecordDecl>(RD)) {
2760assert((CRD->isAggregate() || (Ctx.
getLangOpts().ObjC && VI == VE)) &&
2761 "Non-aggregates are constructed with a constructor!");
2763 for(
const auto&B : CRD->bases()) {
2765assert(!B.isVirtual() &&
"Aggregates cannot have virtual base classes!");
2774assert(BRD &&
"Base classes must be C++ classes!");
2777MRMgr.getCXXBaseObjectRegion(BRD, R,
false);
2779NewB = bindStruct(NewB, BR, *VI);
2787 for(FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI) {
2793 if(FI->isUnnamedBitField())
2797 const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
2800NewB = bindArray(NewB, FR, *VI);
2802NewB = bindStruct(NewB, FR, *VI);
2810NewB = NewB.addBinding(R, BindingKey::Default,
2823 returnremoveSubRegionBindings(B, R).addBinding(R, BindingKey::Default, Val);
2831classRemoveDeadBindingsWorker
2832:
publicClusterAnalysis<RemoveDeadBindingsWorker> {
2838RemoveDeadBindingsWorker(RegionStoreManager &rm,
2842: ClusterAnalysis<RemoveDeadBindingsWorker>(rm, stateMgr,
b),
2843SymReaper(symReaper), CurrentLCtx(LCtx) {}
2848 usingClusterAnalysis<RemoveDeadBindingsWorker>::VisitCluster;
2850 usingClusterAnalysis::AddToWorkList;
2852 boolAddToWorkList(
const MemRegion*R);
2854 boolUpdatePostponed();
2855 voidVisitBinding(
SVal V);
2859boolRemoveDeadBindingsWorker::AddToWorkList(
const MemRegion*R) {
2861 returnAddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
2864voidRemoveDeadBindingsWorker::VisitAddedToCluster(
const MemRegion*baseR,
2867 if(
const VarRegion*VR = dyn_cast<VarRegion>(baseR)) {
2868 if(SymReaper.isLive(VR))
2869AddToWorkList(baseR, &
C);
2874 if(
const SymbolicRegion*SR = dyn_cast<SymbolicRegion>(baseR)) {
2875 if(SymReaper.isLive(SR->getSymbol()))
2876AddToWorkList(SR, &
C);
2878Postponed.push_back(SR);
2883 if(isa<NonStaticGlobalSpaceRegion>(baseR)) {
2884AddToWorkList(baseR, &
C);
2889 if(
const CXXThisRegion*TR = dyn_cast<CXXThisRegion>(baseR)) {
2890 const auto*StackReg =
2894(RegCtx == CurrentLCtx || RegCtx->
isParentOf(CurrentLCtx)))
2895AddToWorkList(TR, &
C);
2899voidRemoveDeadBindingsWorker::VisitCluster(
const MemRegion*baseR,
2906 if(
const SymbolicRegion*SymR = dyn_cast<SymbolicRegion>(baseR))
2907SymReaper.markLive(SymR->getSymbol());
2909 for(
const auto&[Key, Val] : *
C) {
2911SymReaper.markElementIndicesLive(Key.getRegion());
2917voidRemoveDeadBindingsWorker::VisitBinding(
SVal V) {
2921SymReaper.markLazilyCopied(LCS->getRegion());
2923 for(
SVal V: RM.getInterestingValues(*LCS)) {
2925SymReaper.markLazilyCopied(DepLCS->getRegion());
2934 if(
const MemRegion*R =
V.getAsRegion()) {
2936SymReaper.markLive(R);
2940 for(
autoVar : BR->referenced_vars())
2941AddToWorkList(Var.getCapturedRegion());
2948SymReaper.markLive(Sym);
2951boolRemoveDeadBindingsWorker::UpdatePostponed() {
2957 if(SymReaper.isLive(SR->getSymbol())) {
2966StoreRefRegionStoreManager::removeDeadBindings(
Storestore,
2969RegionBindingsRef B = getRegionBindings(store);
2970RemoveDeadBindingsWorker W(*
this, StateMgr, B, SymReaper, LCtx);
2971W.GenerateClusters();
2975W.AddToWorkList(Reg);
2978 doW.RunWorkList();
while(W.UpdatePostponed());
2986 if(!W.isVisited(
Base))
2987B = B.remove(
Base);
2990 return StoreRef(B.asStore(), *
this);
2997voidRegionStoreManager::printJson(raw_ostream &Out,
StoreS,
const char*NL,
2998 unsigned intSpace,
boolIsDot)
const{
2999RegionBindingsRef
Bindings= getRegionBindings(S);
3001Indent(Out, Space, IsDot) <<
"\"store\": ";
3004Out <<
"null,"<< NL;
3008Out <<
"{ \"pointer\": \""<<
Bindings.asStore() <<
"\", \"items\": ["<< NL;
3009 Bindings.printJson(Out, NL, Space + 1, IsDot);
3010Indent(Out, Space, IsDot) <<
"]},"<< NL;
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
static const MemRegion * getRegion(const CallEvent &Call, const MutexDescriptor &Descriptor, bool IsLock)
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
llvm::DenseSet< const void * > Visited
static std::optional< SVal > convertOffsetsFromSvalToUnsigneds(const SmallVector< SVal, 2 > &SrcOffsets, const SmallVector< uint64_t, 2 > ArrayExtents, SmallVector< uint64_t, 2 > &DstOffsets)
llvm::ImmutableMap< const MemRegion *, ClusterBindings > RegionBindings
static std::optional< SVal > getDerivedSymbolForBinding(RegionBindingsConstRef B, const TypedValueRegion *BaseRegion, const TypedValueRegion *SubReg, const ASTContext &Ctx, SValBuilder &SVB)
std::pair< BindingKey, SVal > BindingPair
static bool isCompatibleWithFields(BindingKey K, const FieldVector &Fields)
SmallVector< const FieldDecl *, 8 > FieldVector
llvm::ImmutableMap< BindingKey, SVal > ClusterBindings
static bool isUnionField(const FieldRegion *FR)
static void getSymbolicOffsetFields(BindingKey K, FieldVector &Fields)
static QualType getUnderlyingType(const SubRegion *R)
llvm::ImmutableMapRef< BindingKey, SVal > ClusterBindingsRef
static SmallVector< uint64_t, 2 > getConstantArrayExtents(const ConstantArrayType *CAT)
This is a helper function for getConstantValFromConstArrayInitializer.
static std::pair< SmallVector< SVal, 2 >, const MemRegion * > getElementRegionOffsetsWithBase(const ElementRegion *ER)
This is a helper function for getConstantValFromConstArrayInitializer.
const RegionBindingsRef & RegionBindingsConstRef
static std::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.
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.
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
__PTRDIFF_TYPE__ ptrdiff_t
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const LangOptions & getLangOpts() const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
Stores options for the analyzer from the command line.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Represents a C++ struct/union/class.
Represents the canonical version of C arrays with a specified constant size.
uint64_t getLimitedSize() const
Return the size zero-extended to uint64_t or UINT64_MAX if the value is larger than UINT64_MAX.
uint64_t getZExtSize() const
Return the size zero-extended as a uint64_t.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
This represents one expression.
Represents a member of a struct/union/class.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
Describes an C or C++ initializer list.
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
const Expr * getInit(unsigned Init) const
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
bool isParentOf(const LocationContext *LC) const
const Decl * getDecl() const
const StackFrameContext * getStackFrame() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool isConstQualified() const
Determine whether this type is const-qualified.
Represents a struct/union/class.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
It represents a stack frame of the call stack (based on CallEvent).
Stmt - This represents one statement.
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
bool isVoidPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isScalarType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool isAnyComplexType() const
QualType getCanonicalTypeInternal() const
bool isStructureOrClassType() const
bool isVectorType() const
bool isRecordType() const
Represents a variable declaration or definition.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
Maps string IDs to AST nodes matched by parts of a matcher.
AnalyzerOptions & options
BlockDataRegion - A region that represents a block instance.
CXXThisRegion - Represents the region for the implicit 'this' parameter in a call to a C++ method.
Represents an abstract call to a function or method along a particular path.
ElementRegion is used to represent both array elements and casts.
QualType getElementType() const
RegionRawOffset getAsArrayOffset() const
Compute the offset within the array. The array might also be a subobject.
AnalysisManager & getAnalysisManager()
LLVM_ATTRIBUTE_RETURNS_NONNULL const FieldDecl * getDecl() const override
static bool isLocType(QualType T)
DefinedOrUnknownSVal getStaticSize(const MemRegion *MR, SValBuilder &SVB) const
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemSpaceRegion * getMemorySpace() const
virtual bool isBoundable() const
RegionOffset getAsOffset() const
Compute the offset within the top level memory object.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
bool hasStackNonParametersStorage() const
MemSpaceRegion - A memory region that represents a "memory space"; for example, the set of global var...
Information about invalidation for a particular region/symbol.
@ TK_PreserveContents
Tells that a region's contents is not changed.
@ TK_DoNotInvalidateSuperRegion
@ TK_EntireMemSpace
When applied to a MemSpaceRegion, indicates the entire memory space should be invalidated.
Represent a region's offset within the top level base region.
bool hasSymbolicOffset() const
const MemRegion * getRegion() const
It might return null.
int64_t getOffset() const
const MemRegion * getRegion() const
DefinedOrUnknownSVal makeZeroVal(QualType type)
Construct an SVal representing '0' for the specified type.
NonLoc makeArrayIndex(uint64_t idx)
ASTContext & getContext()
nonloc::ConcreteInt makeIntVal(const IntegerLiteral *integer)
SVal evalCast(SVal V, QualType CastTy, QualType OriginalTy)
Cast a given SVal to another SVal using given QualType's.
DefinedOrUnknownSVal conjureSymbolVal(const void *symbolTag, const Expr *expr, const LocationContext *LCtx, unsigned count)
Create a new symbol with a unique 'name'.
DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(SymbolRef parentSymbol, const TypedValueRegion *region)
loc::ConcreteInt makeNullWithType(QualType type)
Create NULL pointer, with proper pointer bit-width for given address space.
std::optional< SVal > getConstantVal(const Expr *E)
Returns the value of E, if it can be determined in a non-path-sensitive manner.
NonLoc makeZeroArrayIndex()
DefinedOrUnknownSVal getRegionValueSymbolVal(const TypedValueRegion *region)
Make a unique symbol for value of region.
NonLoc makeLazyCompoundVal(const StoreRef &store, const TypedValueRegion *region)
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
bool isZeroConstant() const
bool isUnknownOrUndef() const
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
const MemRegion * getAsRegion() const
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
A utility class that visits the reachable symbols using a custom SymbolVisitor.
bool scan(nonloc::LazyCompoundVal val)
virtual StoreRef invalidateRegions(Store store, ArrayRef< SVal > Values, const Stmt *S, unsigned Count, const LocationContext *LCtx, const CallEvent *Call, InvalidatedSymbols &IS, RegionAndSymbolInvalidationTraits &ITraits, InvalidatedRegions *TopLevelRegions, InvalidatedRegions *Invalidated)=0
invalidateRegions - Clears out the specified regions from the store, marking their values as unknown.
virtual bool scanReachableSymbols(Store S, const MemRegion *R, ScanReachableSymbols &Visitor)=0
Finds the transitive closure of symbols within the given region.
virtual void iterBindings(Store store, BindingsHandler &f)=0
iterBindings - Iterate over the bindings in the Store.
virtual StoreRef getInitialStore(const LocationContext *InitLoc)=0
getInitialStore - Returns the initial "empty" store representing the value bindings upon entry to an ...
virtual StoreRef BindDefaultZero(Store store, const MemRegion *R)=0
Return a store with in which all values within the given region are reset to zero.
virtual std::optional< SVal > getDefaultBinding(Store store, const MemRegion *R)=0
Return the default value bound to a region in a given store.
virtual StoreRef killBinding(Store ST, Loc L)=0
Create a new store with the specified binding removed.
virtual void decrementReferenceCount(Store store)
If the StoreManager supports it, decrement the reference count of the specified Store object.
virtual StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx, SymbolReaper &SymReaper)=0
virtual void incrementReferenceCount(Store store)
If the StoreManager supports it, increment the reference count of the specified Store object.
virtual SVal ArrayToPointer(Loc Array, QualType ElementTy)=0
ArrayToPointer - Used by ExprEngine::VistCast to handle implicit conversions between arrays and point...
virtual bool includedInBindings(Store store, const MemRegion *region) const =0
virtual SVal getBinding(Store store, Loc loc, QualType T=QualType())=0
Return the value bound to specified location in a given state.
virtual StoreRef BindDefaultInitial(Store store, const MemRegion *R, SVal V)=0
Return a store with the specified value bound to all sub-regions of the region.
virtual void printJson(raw_ostream &Out, Store S, const char *NL, unsigned int Space, bool IsDot) const =0
StringRegion - Region associated with a StringLiteral.
SubRegion - A region that subsets another larger region.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const
bool isSubRegionOf(const MemRegion *R) const override
Check if the region is a subregion of the given region.
MemRegionManager & getMemRegionManager() const override
static bool canSymbolicate(QualType T)
A class responsible for cleaning up unused symbols.
llvm::iterator_range< RegionSetTy::const_iterator > regions() const
SymbolicRegion - A special, "non-concrete" region.
TypedRegion - An abstract class representing regions that are typed.
TypedValueRegion - An abstract class representing regions having a typed value.
virtual QualType getValueType() const =0
QualType getLocationType() const override
QualType getValueType() const override
const VarDecl * getDecl() const override=0
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getRegion() const
Get the underlining region.
The simplest example of a concrete compound value is nonloc::CompoundVal, which represents a concrete...
llvm::ImmutableList< SVal >::iterator iterator
Value representing integer constant.
While nonloc::CompoundVal covers a few simple use cases, nonloc::LazyCompoundVal is a more performant...
LLVM_ATTRIBUTE_RETURNS_NONNULL const LazyCompoundValData * getCVData() const
LLVM_ATTRIBUTE_RETURNS_NONNULL const TypedValueRegion * getRegion() const
This function itself is immaterial.
const void * getStore() const
It might return null.
Defines the clang::TargetInfo interface.
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, DeclRefExpr > declRefExpr
Matches expressions that refer to declarations.
const internal::ArgumentAdaptingMatcherFunc< internal::HasDescendantMatcher > hasDescendant
Matches AST nodes that have descendant AST nodes that match the provided matcher.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
internal::Matcher< Stmt > StatementMatcher
const internal::VariadicAllOfMatcher< Stmt > stmt
Matches statements.
llvm::DenseSet< SymbolRef > InvalidatedSymbols
std::unique_ptr< StoreManager > CreateRegionStoreManager(ProgramStateManager &StMgr)
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
ASTEdit remove(RangeSelector S)
Removes the source selected by S.
The JSON file list parser is used to communicate input to InstallAPI.
@ Bind
'bind' clause, allowed on routine constructs.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
const FunctionProtoType * T
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Diagnostic wrappers for TextAPI types for error reporting.
static raw_ostream & operator<<(raw_ostream &Out, BindingKey K)
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4