baloghadamsoftware created this revision. baloghadamsoftware added a reviewer: NoQ. baloghadamsoftware added a project: clang. Herald added subscribers: donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet. Herald added a reviewer: george.karpenkov.
Some operations, especially iterator comparisons are done on a subregion of the original region. Currently, iterator checker does not recognize these comparisons as iterator comparisons since the key for the abstract iterator position in the GDM is the base region, not the subregion. In other parts of the iterator checker we faced similar problems for containers which are always represented as regions. There the solution was to recursively retrieve the base region of `CXXBaseObjectRegion` classes. We apply the same solution now for iterators represented as regions. To avoid code repetition we moved this operation into a separate function. Repository: rC Clang https://reviews.llvm.org/D54466 Files: lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
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<CXXBaseObjectRegion>()) { - 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<CXXBaseObjectRegion>()) { - 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<CXXBaseObjectRegion>()) { - 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<CXXBaseObjectRegion>()) { - 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<CXXBaseObjectRegion>()) { - 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<CXXBaseObjectRegion>()) { - 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<CXXBaseObjectRegion>()) { - 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<CXXBaseObjectRegion>()) { - 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<CXXBaseObjectRegion>()) { - 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<CXXBaseObjectRegion>()) { - 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<CXXBaseObjectRegion>()) { - 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<IteratorRegionMap>(Reg); } else if (const auto Sym = Val.getAsSymbol()) { return State->get<IteratorSymbolMap>(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<IteratorRegionMap>(Reg, Pos); } else if (const auto Sym = Val.getAsSymbol()) { return State->set<IteratorSymbolMap>(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<IteratorRegionMap>(Reg); } else if (const auto Sym = Val.getAsSymbol()) { return State->remove<IteratorSymbolMap>(Sym); @@ -2347,6 +2329,13 @@ return !State->assume(comparison.castAs<DefinedSVal>(), false); } +const MemRegion *getBaseForCXXBase(const MemRegion *Reg) { + while (const auto *CBOR = Reg->getAs<CXXBaseObjectRegion>()) { + Reg = CBOR->getSuperRegion(); + } + return Reg; +} + } // namespace #define REGISTER_CHECKER(name) \
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits