@@ -25,16 +25,20 @@ using namespace ento;
25
25
using namespace taint ;
26
26
27
27
namespace {
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>> {
31
29
void reportBug (StringRef Msg, ProgramStateRef StateZero,
32
30
CheckerContext &C) const ;
33
31
void reportTaintBug (StringRef Msg, ProgramStateRef StateZero,
34
32
CheckerContext &C,
35
33
llvm::ArrayRef<SymbolRef> TaintedSyms) const ;
36
34
37
35
public:
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
+
38
42
void checkPreStmt (const BinaryOperator *B, CheckerContext &C) const ;
39
43
};
40
44
} // end anonymous namespace
@@ -48,8 +52,14 @@ static const Expr *getDenomExpr(const ExplodedNode *N) {
48
52
49
53
void DivZeroChecker::reportBug (StringRef Msg, ProgramStateRef StateZero,
50
54
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" ));
51
60
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);
53
63
bugreporter::trackExpressionValue (N, getDenomExpr (N), *R);
54
64
C.emitReport (std::move (R));
55
65
}
@@ -58,8 +68,15 @@ void DivZeroChecker::reportBug(StringRef Msg, ProgramStateRef StateZero,
58
68
void DivZeroChecker::reportTaintBug (
59
69
StringRef Msg, ProgramStateRef StateZero, CheckerContext &C,
60
70
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);
63
80
bugreporter::trackExpressionValue (N, getDenomExpr (N), *R);
64
81
for (auto Sym : TaintedSyms)
65
82
R->markInteresting (Sym);
@@ -101,8 +118,8 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
101
118
if ((stateNotZero && stateZero)) {
102
119
std::vector<SymbolRef> taintedSyms = getTaintedSymbols (C.getState (), *DV);
103
120
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);
106
123
return ;
107
124
}
108
125
}
@@ -113,9 +130,27 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B,
113
130
}
114
131
115
132
void 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 ();
117
137
}
118
138
119
139
bool ento::shouldRegisterDivZeroChecker (const CheckerManager &mgr) {
120
140
return true ;
121
141
}
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