24using namespace iterator;
28class InvalidatedIteratorChecker
29 :
public Checker<check::PreCall, check::PreStmt<UnaryOperator>,
30 check::PreStmt<BinaryOperator>,
31 check::PreStmt<ArraySubscriptExpr>,
32 check::PreStmt<MemberExpr>> {
34 std::unique_ptr<BugType> InvalidatedBugType;
37 void reportBug(
const StringRef &Message,
const SVal &Val,
40 InvalidatedIteratorChecker();
52InvalidatedIteratorChecker::InvalidatedIteratorChecker() {
53 InvalidatedBugType.reset(
54 new BugType(
this,
"Iterator invalidated",
"Misuse of STL APIs"));
57void InvalidatedIteratorChecker::checkPreCall(
const CallEvent &
Call,
60 const auto *
Func = dyn_cast_or_null<FunctionDecl>(
Call.getDecl());
64 if (
Func->isOverloadedOperator() &&
67 if (
const auto *InstCall = dyn_cast<CXXInstanceCall>(&
Call)) {
68 verifyAccess(
C, InstCall->getCXXThisVal());
70 verifyAccess(
C,
Call.getArgSVal(0));
75void InvalidatedIteratorChecker::checkPreStmt(
const UnaryOperator *UO,
85 verifyAccess(
C, SubVal);
89void InvalidatedIteratorChecker::checkPreStmt(
const BinaryOperator *BO,
93 SVal LVal = State->getSVal(BO->
getLHS(),
C.getLocationContext());
96 verifyAccess(
C, LVal);
103 SVal LVal = State->getSVal(ASE->
getLHS(),
C.getLocationContext());
104 verifyAccess(
C, LVal);
107void InvalidatedIteratorChecker::checkPreStmt(
const MemberExpr *ME,
113 SVal BaseVal = State->getSVal(ME->
getBase(),
C.getLocationContext());
114 verifyAccess(
C, BaseVal);
118 auto State =
C.getState();
120 if (Pos && !Pos->isValid()) {
121 auto *N =
C.generateErrorNode(State);
125 reportBug(
"Invalidated iterator accessed.", Val,
C, N);
129void InvalidatedIteratorChecker::reportBug(
const StringRef &Message,
132 auto R = std::make_unique<PathSensitiveBugReport>(*InvalidatedBugType,
134 R->markInteresting(Val);
135 C.emitReport(std::move(R));
138void ento::registerInvalidatedIteratorChecker(
CheckerManager &mgr) {
142bool ento::shouldRegisterInvalidatedIteratorChecker(
const CheckerManager &mgr) {
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
A builtin binary operation expression such as "x + y" or "x <= y".
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
bool isImplicitAccess() const
Determine whether the base of this explicit is implicit.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represents an abstract call to a function or method along a particular path.
CHECKER * registerChecker(AT &&... Args)
Used to register checkers.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
bool isAccessOperator(OverloadedOperatorKind OK)
const IteratorPosition * getIteratorPosition(ProgramStateRef State, const SVal &Val)