Index: lib/StaticAnalyzer/Checkers/IteratorChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/IteratorChecker.cpp +++ lib/StaticAnalyzer/Checkers/IteratorChecker.cpp @@ -390,6 +390,7 @@ const MemRegion *Reg); bool isOutOfRange(ProgramStateRef State, const IteratorPosition &Pos); bool isZero(ProgramStateRef State, const NonLoc &Val); +const MemRegion *getBaseForCXXBase(const MemRegion *Reg); } // namespace IteratorChecker::IteratorChecker() { @@ -1089,9 +1090,7 @@ void IteratorChecker::verifyMatch(CheckerContext &C, const SVal &Iter, const MemRegion *Cont) const { // Verify match between a container and the container of an iterator - while (const auto *CBOR = Cont->getAs()) { - Cont = CBOR->getSuperRegion(); - } + Cont = getBaseForCXXBase(Cont); auto State = C.getState(); const auto *Pos = getIteratorPosition(State, Iter); @@ -1125,9 +1124,7 @@ if (!ContReg) return; - while (const auto *CBOR = ContReg->getAs()) { - ContReg = CBOR->getSuperRegion(); - } + ContReg = getBaseForCXXBase(ContReg); // If the container already has a begin symbol then use it. Otherwise first // create a new one. @@ -1151,9 +1148,7 @@ if (!ContReg) return; - while (const auto *CBOR = ContReg->getAs()) { - ContReg = CBOR->getSuperRegion(); - } + ContReg = getBaseForCXXBase(ContReg); // If the container already has an end symbol then use it. Otherwise first // create a new one. @@ -1174,9 +1169,7 @@ void IteratorChecker::assignToContainer(CheckerContext &C, const Expr *CE, const SVal &RetVal, const MemRegion *Cont) const { - while (const auto *CBOR = Cont->getAs()) { - Cont = CBOR->getSuperRegion(); - } + Cont = getBaseForCXXBase(Cont); auto State = C.getState(); auto &SymMgr = C.getSymbolManager(); @@ -1194,9 +1187,7 @@ if (!ContReg) return; - while (const auto *CBOR = ContReg->getAs()) { - ContReg = CBOR->getSuperRegion(); - } + ContReg = getBaseForCXXBase(ContReg); // Assignment of a new value to a container always invalidates all its // iterators @@ -1211,9 +1202,7 @@ if (!OldCont.isUndef()) { const auto *OldContReg = OldCont.getAsRegion(); if (OldContReg) { - while (const auto *CBOR = OldContReg->getAs()) { - OldContReg = CBOR->getSuperRegion(); - } + OldContReg = getBaseForCXXBase(OldContReg); const auto OldCData = getContainerData(State, OldContReg); if (OldCData) { if (const auto OldEndSym = OldCData->getEnd()) { @@ -1273,9 +1262,7 @@ if (!ContReg) return; - while (const auto *CBOR = ContReg->getAs()) { - ContReg = CBOR->getSuperRegion(); - } + ContReg = getBaseForCXXBase(ContReg); // The clear() operation invalidates all the iterators, except the past-end // iterators of list-like containers @@ -1302,9 +1289,7 @@ if (!ContReg) return; - while (const auto *CBOR = ContReg->getAs()) { - ContReg = CBOR->getSuperRegion(); - } + ContReg = getBaseForCXXBase(ContReg); // For deque-like containers invalidate all iterator positions auto State = C.getState(); @@ -1341,9 +1326,7 @@ if (!ContReg) return; - while (const auto *CBOR = ContReg->getAs()) { - ContReg = CBOR->getSuperRegion(); - } + ContReg = getBaseForCXXBase(ContReg); auto State = C.getState(); const auto CData = getContainerData(State, ContReg); @@ -1381,9 +1364,7 @@ if (!ContReg) return; - while (const auto *CBOR = ContReg->getAs()) { - ContReg = CBOR->getSuperRegion(); - } + ContReg = getBaseForCXXBase(ContReg); // For deque-like containers invalidate all iterator positions auto State = C.getState(); @@ -1416,9 +1397,7 @@ if (!ContReg) return; - while (const auto *CBOR = ContReg->getAs()) { - ContReg = CBOR->getSuperRegion(); - } + ContReg = getBaseForCXXBase(ContReg); auto State = C.getState(); const auto CData = getContainerData(State, ContReg); @@ -2015,7 +1994,8 @@ const IteratorPosition *getIteratorPosition(ProgramStateRef State, const SVal &Val) { - if (const auto Reg = Val.getAsRegion()) { + if (auto Reg = Val.getAsRegion()) { + Reg = getBaseForCXXBase(Reg); return State->get(Reg); } else if (const auto Sym = Val.getAsSymbol()) { return State->get(Sym); @@ -2037,7 +2017,8 @@ ProgramStateRef setIteratorPosition(ProgramStateRef State, const SVal &Val, const IteratorPosition &Pos) { - if (const auto Reg = Val.getAsRegion()) { + if (auto Reg = Val.getAsRegion()) { + Reg = getBaseForCXXBase(Reg); return State->set(Reg, Pos); } else if (const auto Sym = Val.getAsSymbol()) { return State->set(Sym, Pos); @@ -2060,7 +2041,8 @@ } ProgramStateRef removeIteratorPosition(ProgramStateRef State, const SVal &Val) { - if (const auto Reg = Val.getAsRegion()) { + if (auto Reg = Val.getAsRegion()) { + Reg = getBaseForCXXBase(Reg); return State->remove(Reg); } else if (const auto Sym = Val.getAsSymbol()) { return State->remove(Sym); @@ -2347,6 +2329,13 @@ return !State->assume(comparison.castAs(), false); } +const MemRegion *getBaseForCXXBase(const MemRegion *Reg) { + while (const auto *CBOR = Reg->getAs()) { + Reg = CBOR->getSuperRegion(); + } + return Reg; +} + } // namespace #define REGISTER_CHECKER(name) \