28class DebugIteratorModeling
31 const BugType DebugMsgBugType{
this,
"Checking analyzer assumptions",
"debug",
34 template <
typename Getter>
35 void analyzerIteratorDataField(
const CallExpr *CE, CheckerContext &
C,
36 Getter get, SVal
Default)
const;
37 void analyzerIteratorPosition(
const CallExpr *CE, CheckerContext &
C)
const;
38 void analyzerIteratorContainer(
const CallExpr *CE, CheckerContext &
C)
const;
39 void analyzerIteratorValidity(
const CallExpr *CE, CheckerContext &
C)
const;
40 ExplodedNode *reportDebugMsg(llvm::StringRef Msg, CheckerContext &
C)
const;
42 typedef void (DebugIteratorModeling::*FnCheck)(
const CallExpr *,
43 CheckerContext &)
const;
45 CallDescriptionMap<FnCheck> Callbacks = {
46 {{CDM::SimpleFunc, {
"clang_analyzer_iterator_position"}, 1},
47 &DebugIteratorModeling::analyzerIteratorPosition},
48 {{CDM::SimpleFunc, {
"clang_analyzer_iterator_container"}, 1},
49 &DebugIteratorModeling::analyzerIteratorContainer},
50 {{CDM::SimpleFunc, {
"clang_analyzer_iterator_validity"}, 1},
51 &DebugIteratorModeling::analyzerIteratorValidity},
55 bool evalCall(
const CallEvent &
Call, CheckerContext &
C)
const;
62 const auto *CE = dyn_cast_or_null<CallExpr>(
Call.getOriginExpr());
66 const FnCheck *Handler = Callbacks.lookup(
Call);
70 (this->**Handler)(CE,
C);
74template <
typename Getter>
75void DebugIteratorModeling::analyzerIteratorDataField(
const CallExpr *CE,
80 reportDebugMsg(
"Missing iterator argument",
C);
84 auto State =
C.getState();
88 State = State->BindExpr(CE,
C.getLocationContext(), get(Pos));
90 State = State->BindExpr(CE,
C.getLocationContext(),
Default);
92 C.addTransition(State);
95void DebugIteratorModeling::analyzerIteratorPosition(
const CallExpr *CE,
96 CheckerContext &
C)
const {
97 auto &BVF =
C.getSValBuilder().getBasicValueFactory();
98 analyzerIteratorDataField(CE,
C, [](
const IteratorPosition *P) {
100 }, nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0))));
103void DebugIteratorModeling::analyzerIteratorContainer(
const CallExpr *CE,
104 CheckerContext &
C)
const {
105 auto &BVF =
C.getSValBuilder().getBasicValueFactory();
106 analyzerIteratorDataField(CE,
C, [](
const IteratorPosition *P) {
108 }, loc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0))));
111void DebugIteratorModeling::analyzerIteratorValidity(
const CallExpr *CE,
112 CheckerContext &
C)
const {
113 auto &BVF =
C.getSValBuilder().getBasicValueFactory();
114 analyzerIteratorDataField(CE,
C, [&BVF](
const IteratorPosition *P) {
116 nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get((P->
isValid()))));
117 }, nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(0))));
120ExplodedNode *DebugIteratorModeling::reportDebugMsg(llvm::StringRef Msg,
121 CheckerContext &
C)
const {
122 ExplodedNode *N =
C.generateNonFatalErrorNode();
126 auto &BR =
C.getBugReporter();
128 std::make_unique<PathSensitiveBugReport>(DebugMsgBugType, Msg, N));
132void ento::registerDebugIteratorModeling(CheckerManager &mgr) {
136bool ento::shouldRegisterDebugIteratorModeling(
const CheckerManager &mgr) {
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
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)
The JSON file list parser is used to communicate input to InstallAPI.
SymbolRef getOffset() const
const MemRegion * getContainer() const