28class InvalidatedIteratorChecker
29 :
public Checker<check::PreCall, check::PreStmt<UnaryOperator>,
30 check::PreStmt<BinaryOperator>,
31 check::PreStmt<ArraySubscriptExpr>,
32 check::PreStmt<MemberExpr>> {
34 const BugType InvalidatedBugType{
this,
"Iterator invalidated",
35 "Misuse of STL APIs"};
37 void verifyAccess(CheckerContext &
C, SVal Val)
const;
38 void reportBug(StringRef Message, SVal Val, CheckerContext &
C,
39 ExplodedNode *ErrNode)
const;
42 void checkPreCall(
const CallEvent &
Call, CheckerContext &
C)
const;
43 void checkPreStmt(
const UnaryOperator *UO, CheckerContext &
C)
const;
44 void checkPreStmt(
const BinaryOperator *BO, CheckerContext &
C)
const;
45 void checkPreStmt(
const ArraySubscriptExpr *ASE, CheckerContext &
C)
const;
46 void checkPreStmt(
const MemberExpr *ME, CheckerContext &
C)
const;
52void InvalidatedIteratorChecker::checkPreCall(
const CallEvent &
Call,
55 const auto *
Func = dyn_cast_or_null<FunctionDecl>(
Call.getDecl());
59 if (
Func->isOverloadedOperator() &&
62 if (
const auto *InstCall = dyn_cast<CXXInstanceCall>(&
Call)) {
63 verifyAccess(
C, InstCall->getCXXThisVal());
65 verifyAccess(
C,
Call.getArgSVal(0));
70void InvalidatedIteratorChecker::checkPreStmt(
const UnaryOperator *UO,
71 CheckerContext &
C)
const {
77 SVal SubVal = State->getSVal(UO->
getSubExpr(),
C.getLocationContext());
80 verifyAccess(
C, SubVal);
84void InvalidatedIteratorChecker::checkPreStmt(
const BinaryOperator *BO,
85 CheckerContext &
C)
const {
88 SVal LVal = State->getSVal(BO->
getLHS(),
C.getLocationContext());
91 verifyAccess(
C, LVal);
95void InvalidatedIteratorChecker::checkPreStmt(
const ArraySubscriptExpr *ASE,
96 CheckerContext &
C)
const {
98 SVal LVal = State->getSVal(ASE->
getLHS(),
C.getLocationContext());
99 verifyAccess(
C, LVal);
102void InvalidatedIteratorChecker::checkPreStmt(
const MemberExpr *ME,
103 CheckerContext &
C)
const {
108 SVal BaseVal = State->getSVal(ME->
getBase(),
C.getLocationContext());
109 verifyAccess(
C, BaseVal);
112void InvalidatedIteratorChecker::verifyAccess(CheckerContext &
C,
114 auto State =
C.getState();
116 if (Pos && !Pos->isValid()) {
117 auto *N =
C.generateErrorNode(State);
121 reportBug(
"Invalidated iterator accessed.", Val,
C, N);
125void InvalidatedIteratorChecker::reportBug(StringRef Message, SVal Val,
127 ExplodedNode *ErrNode)
const {
128 auto R = std::make_unique<PathSensitiveBugReport>(InvalidatedBugType, Message,
130 R->markInteresting(Val);
131 C.emitReport(std::move(R));
134void ento::registerInvalidatedIteratorChecker(CheckerManager &mgr) {
138bool ento::shouldRegisterInvalidatedIteratorChecker(
const CheckerManager &mgr) {
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
bool isImplicitAccess() const
Determine whether the base of this explicit is implicit.
Expr * getSubExpr() const
Represents an abstract call to a function or method along a particular path.
CHECKER * registerChecker(AT &&...Args)
Register a single-part checker (derived from Checker): construct its singleton instance,...
Simple checker classes that implement one frontend (i.e.
const IteratorPosition * getIteratorPosition(ProgramStateRef State, SVal Val)
bool isAccessOperator(OverloadedOperatorKind OK)
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)