Index: lib/StaticAnalyzer/Checkers/IteratorChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/IteratorChecker.cpp +++ lib/StaticAnalyzer/Checkers/IteratorChecker.cpp @@ -168,7 +168,7 @@ class IteratorChecker : public Checker, - check::DeadSymbols, + check::LiveSymbols, check::DeadSymbols, eval::Assume> { std::unique_ptr OutOfRangeBugType; @@ -198,6 +198,7 @@ void checkPostCall(const CallEvent &Call, CheckerContext &C) const; void checkPostStmt(const MaterializeTemporaryExpr *MTE, CheckerContext &C) const; + void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const; void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const; ProgramStateRef evalAssume(ProgramStateRef State, SVal Cond, bool Assumption) const; @@ -363,6 +364,22 @@ C.addTransition(State); } +void IteratorChecker::checkLiveSymbols(ProgramStateRef State, + SymbolReaper &SR) const { + // Keep containers alive while iterators are alive + auto RegionMap = State->get(); + for (const auto Reg : RegionMap) { + const auto Pos = Reg.second; + SR.markLive(Pos.getContainer()); + } + + auto SymbolMap = State->get(); + for (const auto Sym : SymbolMap) { + const auto Pos = Sym.second; + SR.markLive(Pos.getContainer()); + } +} + void IteratorChecker::checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const { // Cleanup @@ -395,6 +412,8 @@ State = State->remove(Comp.first); } } + + C.addTransition(State); } ProgramStateRef IteratorChecker::evalAssume(ProgramStateRef State, SVal Cond,