#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "Iterator.h"
usingnamespaceclang;
usingnamespaceento;
usingnamespaceiterator;
namespace {
class IteratorRangeChecker
: public Checker<check::PreCall, check::PreStmt<UnaryOperator>,
check::PreStmt<BinaryOperator>,
check::PreStmt<ArraySubscriptExpr>,
check::PreStmt<MemberExpr>> { … };
bool isPastTheEnd(ProgramStateRef State, const IteratorPosition &Pos);
bool isAheadOfRange(ProgramStateRef State, const IteratorPosition &Pos);
bool isBehindPastTheEnd(ProgramStateRef State, const IteratorPosition &Pos);
bool isZero(ProgramStateRef State, NonLoc Val);
}
void IteratorRangeChecker::checkPreCall(const CallEvent &Call,
CheckerContext &C) const { … }
void IteratorRangeChecker::checkPreStmt(const UnaryOperator *UO,
CheckerContext &C) const { … }
void IteratorRangeChecker::checkPreStmt(const BinaryOperator *BO,
CheckerContext &C) const { … }
void IteratorRangeChecker::checkPreStmt(const ArraySubscriptExpr *ASE,
CheckerContext &C) const { … }
void IteratorRangeChecker::checkPreStmt(const MemberExpr *ME,
CheckerContext &C) const { … }
void IteratorRangeChecker::verifyDereference(CheckerContext &C,
SVal Val) const { … }
void IteratorRangeChecker::verifyIncrement(CheckerContext &C, SVal Iter) const { … }
void IteratorRangeChecker::verifyDecrement(CheckerContext &C, SVal Iter) const { … }
void IteratorRangeChecker::verifyRandomIncrOrDecr(CheckerContext &C,
OverloadedOperatorKind Op,
SVal LHS, SVal RHS) const { … }
void IteratorRangeChecker::verifyAdvance(CheckerContext &C, SVal LHS,
SVal RHS) const { … }
void IteratorRangeChecker::verifyPrev(CheckerContext &C, SVal LHS,
SVal RHS) const { … }
void IteratorRangeChecker::verifyNext(CheckerContext &C, SVal LHS,
SVal RHS) const { … }
void IteratorRangeChecker::reportBug(StringRef Message, SVal Val,
CheckerContext &C,
ExplodedNode *ErrNode) const { … }
namespace {
bool isLess(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2);
bool isGreater(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2);
bool isEqual(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2);
bool isZero(ProgramStateRef State, NonLoc Val) { … }
bool isPastTheEnd(ProgramStateRef State, const IteratorPosition &Pos) { … }
bool isAheadOfRange(ProgramStateRef State, const IteratorPosition &Pos) { … }
bool isBehindPastTheEnd(ProgramStateRef State, const IteratorPosition &Pos) { … }
bool isLess(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2) { … }
bool isGreater(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2) { … }
bool isEqual(ProgramStateRef State, SymbolRef Sym1, SymbolRef Sym2) { … }
}
void ento::registerIteratorRangeChecker(CheckerManager &mgr) { … }
bool ento::shouldRegisterIteratorRangeChecker(const CheckerManager &mgr) { … }