From cfca06d7963fa0909f90483b42a6d7d194d01e08 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 26 Jul 2020 19:36:28 +0000 Subject: Vendor import of llvm-project master 2e10b7a39b9, the last commit before the llvmorg-12-init tag, from which release/11.x was branched. --- .../Checkers/InvalidatedIteratorChecker.cpp | 53 +++++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) (limited to 'clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp') diff --git a/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp index d1a9a7df071d..6955ba11a28f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/InvalidatedIteratorChecker.cpp @@ -26,7 +26,10 @@ using namespace iterator; namespace { class InvalidatedIteratorChecker - : public Checker { + : public Checker, + check::PreStmt, + check::PreStmt, + check::PreStmt> { std::unique_ptr InvalidatedBugType; @@ -37,6 +40,10 @@ public: InvalidatedIteratorChecker(); void checkPreCall(const CallEvent &Call, CheckerContext &C) const; + void checkPreStmt(const UnaryOperator *UO, CheckerContext &C) const; + void checkPreStmt(const BinaryOperator *BO, CheckerContext &C) const; + void checkPreStmt(const ArraySubscriptExpr *ASE, CheckerContext &C) const; + void checkPreStmt(const MemberExpr *ME, CheckerContext &C) const; }; @@ -65,6 +72,48 @@ void InvalidatedIteratorChecker::checkPreCall(const CallEvent &Call, } } +void InvalidatedIteratorChecker::checkPreStmt(const UnaryOperator *UO, + CheckerContext &C) const { + if (isa(UO->getSubExpr())) + return; + + ProgramStateRef State = C.getState(); + UnaryOperatorKind OK = UO->getOpcode(); + SVal SubVal = State->getSVal(UO->getSubExpr(), C.getLocationContext()); + + if (isAccessOperator(OK)) { + verifyAccess(C, SubVal); + } +} + +void InvalidatedIteratorChecker::checkPreStmt(const BinaryOperator *BO, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + BinaryOperatorKind OK = BO->getOpcode(); + SVal LVal = State->getSVal(BO->getLHS(), C.getLocationContext()); + + if (isAccessOperator(OK)) { + verifyAccess(C, LVal); + } +} + +void InvalidatedIteratorChecker::checkPreStmt(const ArraySubscriptExpr *ASE, + CheckerContext &C) const { + ProgramStateRef State = C.getState(); + SVal LVal = State->getSVal(ASE->getLHS(), C.getLocationContext()); + verifyAccess(C, LVal); +} + +void InvalidatedIteratorChecker::checkPreStmt(const MemberExpr *ME, + CheckerContext &C) const { + if (!ME->isArrow() || ME->isImplicitAccess()) + return; + + ProgramStateRef State = C.getState(); + SVal BaseVal = State->getSVal(ME->getBase(), C.getLocationContext()); + verifyAccess(C, BaseVal); +} + void InvalidatedIteratorChecker::verifyAccess(CheckerContext &C, const SVal &Val) const { auto State = C.getState(); const auto *Pos = getIteratorPosition(State, Val); @@ -90,6 +139,6 @@ void ento::registerInvalidatedIteratorChecker(CheckerManager &mgr) { mgr.registerChecker(); } -bool ento::shouldRegisterInvalidatedIteratorChecker(const LangOptions &LO) { +bool ento::shouldRegisterInvalidatedIteratorChecker(const CheckerManager &mgr) { return true; } -- cgit v1.2.3