#include "clang/AST/DeclTemplate.h"
#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 "clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h"
#include "llvm/ADT/STLExtras.h"
#include "Iterator.h"
#include <utility>
usingnamespaceclang;
usingnamespaceento;
usingnamespaceiterator;
namespace {
class IteratorModeling
: public Checker<check::PostCall, check::PostStmt<UnaryOperator>,
check::PostStmt<BinaryOperator>,
check::PostStmt<MaterializeTemporaryExpr>,
check::Bind, check::LiveSymbols, check::DeadSymbols> { … };
bool isSimpleComparisonOperator(OverloadedOperatorKind OK);
bool isSimpleComparisonOperator(BinaryOperatorKind OK);
ProgramStateRef removeIteratorPosition(ProgramStateRef State, SVal Val);
ProgramStateRef relateSymbols(ProgramStateRef State, SymbolRef Sym1,
SymbolRef Sym2, bool Equal);
bool isBoundThroughLazyCompoundVal(const Environment &Env,
const MemRegion *Reg);
const ExplodedNode *findCallEnter(const ExplodedNode *Node, const Expr *Call);
}
void IteratorModeling::checkPostCall(const CallEvent &Call,
CheckerContext &C) const { … }
void IteratorModeling::checkBind(SVal Loc, SVal Val, const Stmt *S,
CheckerContext &C) const { … }
void IteratorModeling::checkPostStmt(const UnaryOperator *UO,
CheckerContext &C) const { … }
void IteratorModeling::checkPostStmt(const BinaryOperator *BO,
CheckerContext &C) const { … }
void IteratorModeling::checkPostStmt(const MaterializeTemporaryExpr *MTE,
CheckerContext &C) const { … }
void IteratorModeling::checkLiveSymbols(ProgramStateRef State,
SymbolReaper &SR) const { … }
void IteratorModeling::checkDeadSymbols(SymbolReaper &SR,
CheckerContext &C) const { … }
void
IteratorModeling::handleOverloadedOperator(CheckerContext &C,
const CallEvent &Call,
OverloadedOperatorKind Op) const { … }
void
IteratorModeling::handleAdvanceLikeFunction(CheckerContext &C,
const CallEvent &Call,
const Expr *OrigExpr,
const AdvanceFn *Handler) const { … }
void IteratorModeling::handleComparison(CheckerContext &C, const Expr *CE,
SVal RetVal, SVal LVal, SVal RVal,
OverloadedOperatorKind Op) const { … }
void IteratorModeling::processComparison(CheckerContext &C,
ProgramStateRef State, SymbolRef Sym1,
SymbolRef Sym2, SVal RetVal,
OverloadedOperatorKind Op) const { … }
void IteratorModeling::handleIncrement(CheckerContext &C, SVal RetVal,
SVal Iter, bool Postfix) const { … }
void IteratorModeling::handleDecrement(CheckerContext &C, SVal RetVal,
SVal Iter, bool Postfix) const { … }
void IteratorModeling::handleRandomIncrOrDecr(CheckerContext &C, const Expr *CE,
OverloadedOperatorKind Op,
SVal RetVal, SVal Iterator,
SVal Amount) const { … }
void IteratorModeling::handlePtrIncrOrDecr(CheckerContext &C,
const Expr *Iterator,
OverloadedOperatorKind OK,
SVal Offset) const { … }
void IteratorModeling::handleAdvance(CheckerContext &C, const Expr *CE,
SVal RetVal, SVal Iter,
SVal Amount) const { … }
void IteratorModeling::handlePrev(CheckerContext &C, const Expr *CE,
SVal RetVal, SVal Iter, SVal Amount) const { … }
void IteratorModeling::handleNext(CheckerContext &C, const Expr *CE,
SVal RetVal, SVal Iter, SVal Amount) const { … }
void IteratorModeling::assignToContainer(CheckerContext &C, const Expr *CE,
SVal RetVal,
const MemRegion *Cont) const { … }
bool IteratorModeling::noChangeInAdvance(CheckerContext &C, SVal Iter,
const Expr *CE) const { … }
void IteratorModeling::printState(raw_ostream &Out, ProgramStateRef State,
const char *NL, const char *Sep) const { … }
namespace {
bool isSimpleComparisonOperator(OverloadedOperatorKind OK) { … }
bool isSimpleComparisonOperator(BinaryOperatorKind OK) { … }
ProgramStateRef removeIteratorPosition(ProgramStateRef State, SVal Val) { … }
ProgramStateRef relateSymbols(ProgramStateRef State, SymbolRef Sym1,
SymbolRef Sym2, bool Equal) { … }
bool isBoundThroughLazyCompoundVal(const Environment &Env,
const MemRegion *Reg) { … }
const ExplodedNode *findCallEnter(const ExplodedNode *Node, const Expr *Call) { … }
}
void ento::registerIteratorModeling(CheckerManager &mgr) { … }
bool ento::shouldRegisterIteratorModeling(const CheckerManager &mgr) { … }