diff options
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/IteratorChecker.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/IteratorChecker.cpp | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp b/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp index 56c250cd16783..520c32e1c7703 100644 --- a/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp @@ -291,6 +291,7 @@ const ContainerData *getContainerData(ProgramStateRef State, const MemRegion *Cont); ProgramStateRef setContainerData(ProgramStateRef State, const MemRegion *Cont, const ContainerData &CData); +bool hasLiveIterators(ProgramStateRef State, const MemRegion *Cont); bool isOutOfRange(ProgramStateRef State, const IteratorPosition &Pos); bool isZero(ProgramStateRef State, const NonLoc &Val); } // namespace @@ -536,7 +537,11 @@ void IteratorChecker::checkDeadSymbols(SymbolReaper &SR, auto ContMap = State->get<ContainerMap>(); for (const auto Cont : ContMap) { if (!SR.isLiveRegion(Cont.first)) { - State = State->remove<ContainerMap>(Cont.first); + // We must keep the container data while it has live iterators to be able + // to compare them to the begin and the end of the container. + if (!hasLiveIterators(State, Cont.first)) { + State = State->remove<ContainerMap>(Cont.first); + } } } @@ -546,6 +551,8 @@ void IteratorChecker::checkDeadSymbols(SymbolReaper &SR, State = State->remove<IteratorComparisonMap>(Comp.first); } } + + C.addTransition(State); } ProgramStateRef IteratorChecker::evalAssume(ProgramStateRef State, SVal Cond, @@ -1188,6 +1195,22 @@ ProgramStateRef relateIteratorPositions(ProgramStateRef State, return NewState; } +bool hasLiveIterators(ProgramStateRef State, const MemRegion *Cont) { + auto RegionMap = State->get<IteratorRegionMap>(); + for (const auto Reg : RegionMap) { + if (Reg.second.getContainer() == Cont) + return true; + } + + auto SymbolMap = State->get<IteratorSymbolMap>(); + for (const auto Sym : SymbolMap) { + if (Sym.second.getContainer() == Cont) + return true; + } + + return false; +} + bool isZero(ProgramStateRef State, const NonLoc &Val) { auto &BVF = State->getBasicVals(); return compare(State, Val, |