@@ -25,16 +25,20 @@ using namespace ento;
2525using namespace taint ;
2626
2727namespace {
28- class DivZeroChecker : public Checker < check::PreStmt<BinaryOperator> > {
29- const BugType BT{this , " Division by zero" };
30- const BugType TaintBT{this , " Division by zero" , categories::TaintedData};
28+ class DivZeroChecker : public Checker <check::PreStmt<BinaryOperator>> {
3129 void reportBug (StringRef Msg, ProgramStateRef StateZero,
3230 CheckerContext &C) const ;
3331 void reportTaintBug (StringRef Msg, ProgramStateRef StateZero,
3432 CheckerContext &C,
3533 llvm::ArrayRef<SymbolRef> TaintedSyms) const ;
3634
3735public:
36+ // / This checker class implements several user facing checkers
37+ enum CheckKind { CK_DivideZero, CK_TaintedDivChecker, CK_NumCheckKinds };
38+ bool ChecksEnabled[CK_NumCheckKinds] = {false };
39+ CheckerNameRef CheckNames[CK_NumCheckKinds];
40+ mutable std::unique_ptr<BugType> BugTypes[CK_NumCheckKinds];
41+
3842 void checkPreStmt (const BinaryOperator *B, CheckerContext &C) const ;
3943};
4044} // end anonymous namespace
@@ -48,8 +52,14 @@ static const Expr *getDenomExpr(const ExplodedNode *N) {
4852
4953void DivZeroChecker::reportBug (StringRef Msg, ProgramStateRef StateZero,
5054 CheckerContext &C) const {
55+ if (!ChecksEnabled[CK_DivideZero])
56+ return ;
57+ if (!BugTypes[CK_DivideZero])
58+ BugTypes[CK_DivideZero].reset (
59+ new BugType (CheckNames[CK_DivideZero], " Division by zero" ));
5160 if (ExplodedNode *N = C.generateErrorNode (StateZero)) {
52- auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, N);
61+ auto R = std::make_unique<PathSensitiveBugReport>(*BugTypes[CK_DivideZero],
62+ Msg, N);
5363 bugreporter::trackExpressionValue (N, getDenomExpr (N), *R);
5464 C.emitReport (std::move (R));
5565 }
@@ -58,8 +68,15 @@ void DivZeroChecker::reportBug(StringRef Msg, ProgramStateRef StateZero,
5868void DivZeroChecker::reportTaintBug (
5969 StringRef Msg, ProgramStateRef StateZero, CheckerContext &C,
6070 llvm::ArrayRef<SymbolRef> TaintedSyms) const {
61- if (ExplodedNode *N = C.generateErrorNode (StateZero)) {
62- auto R = std::make_unique<PathSensitiveBugReport>(TaintBT, Msg, N);
71+ if (!ChecksEnabled[CK_TaintedDivChecker])
72+ return ;
73+ if (!BugTypes[CK_TaintedDivChecker])
74+ BugTypes[CK_TaintedDivChecker].reset (
75+ new BugType (CheckNames[CK_TaintedDivChecker], " Division by zero" ,
76+ categories::TaintedData));
77+ if (ExplodedNode *N = C.generateNonFatalErrorNode (StateZero)) {
78+ auto R = std::make_unique<PathSensitiveBugReport>(
79+ *BugTypes[CK_TaintedDivChecker], Msg, N);
6380 bugreporter::trackExpressionValue (N, getDenomExpr (N), *R);
6481 for (auto Sym : TaintedSyms)
6582 R->markInteresting (Sym);
@@ -101,8 +118,8 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
101118 if ((stateNotZero && stateZero)) {
102119 std::vector<SymbolRef> taintedSyms = getTaintedSymbols (C.getState (), *DV);
103120 if (!taintedSyms.empty ()) {
104- reportTaintBug (" Division by a tainted value, possibly zero" , stateZero, C ,
105- taintedSyms);
121+ reportTaintBug (" Division by a tainted value, possibly zero" , stateNotZero ,
122+ C, taintedSyms);
106123 return ;
107124 }
108125 }
@@ -113,9 +130,27 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
113130}
114131
115132void ento::registerDivZeroChecker (CheckerManager &mgr) {
116- mgr.registerChecker <DivZeroChecker>();
133+ DivZeroChecker *checker = mgr.registerChecker <DivZeroChecker>();
134+ checker->ChecksEnabled [DivZeroChecker::CK_DivideZero] = true ;
135+ checker->CheckNames [DivZeroChecker::CK_DivideZero] =
136+ mgr.getCurrentCheckerName ();
117137}
118138
119139bool ento::shouldRegisterDivZeroChecker (const CheckerManager &mgr) {
120140 return true ;
121141}
142+
143+ void ento::registerTaintedDivChecker (CheckerManager &mgr) {
144+ DivZeroChecker *checker;
145+ if (!mgr.isRegisteredChecker <DivZeroChecker>())
146+ checker = mgr.registerChecker <DivZeroChecker>();
147+ else
148+ checker = mgr.getChecker <DivZeroChecker>();
149+ checker->ChecksEnabled [DivZeroChecker::CK_TaintedDivChecker] = true ;
150+ checker->CheckNames [DivZeroChecker::CK_TaintedDivChecker] =
151+ mgr.getCurrentCheckerName ();
152+ }
153+
154+ bool ento::shouldRegisterTaintedDivChecker (const CheckerManager &mgr) {
155+ return true ;
156+ }
0 commit comments