28class DivZeroChecker :
public CheckerFamily<check::PreStmt<BinaryOperator>> {
30 CheckerContext &
C)
const;
33 llvm::ArrayRef<SymbolRef> TaintedSyms)
const;
37 CheckerFrontendWithBugType DivideZeroChecker{
"Division by zero"};
38 CheckerFrontendWithBugType TaintedDivChecker{
"Division by zero",
41 void checkPreStmt(
const BinaryOperator *B, CheckerContext &
C)
const;
44 StringRef getDebugTag()
const override {
return "DivZeroChecker"; }
50 if (
const auto *BE = dyn_cast<BinaryOperator>(S))
59 if (ExplodedNode *N =
C.generateErrorNode(StateZero)) {
61 std::make_unique<PathSensitiveBugReport>(DivideZeroChecker, Msg, N);
63 C.emitReport(std::move(R));
67void DivZeroChecker::reportTaintBug(
69 llvm::ArrayRef<SymbolRef> TaintedSyms)
const {
72 if (ExplodedNode *N =
C.generateErrorNode(StateZero)) {
74 std::make_unique<PathSensitiveBugReport>(TaintedDivChecker, Msg, N);
76 for (
auto Sym : TaintedSyms)
77 R->markInteresting(Sym);
78 C.emitReport(std::move(R));
82void DivZeroChecker::checkPreStmt(
const BinaryOperator *B,
83 CheckerContext &
C)
const {
94 SVal Denom =
C.getSVal(B->
getRHS());
95 std::optional<DefinedSVal> DV = Denom.
getAs<DefinedSVal>();
103 ConstraintManager &CM =
C.getConstraintManager();
105 std::tie(stateNotZero, stateZero) = CM.
assumeDual(
C.getState(), *DV);
109 reportBug(
"Division by zero", stateZero,
C);
113 if ((stateNotZero && stateZero)) {
115 if (!taintedSyms.empty()) {
116 reportTaintBug(
"Division by a tainted value, possibly zero", stateZero,
C,
124 C.addTransition(stateNotZero);
127void ento::registerDivZeroChecker(CheckerManager &Mgr) {
128 Mgr.
getChecker<DivZeroChecker>()->DivideZeroChecker.enable(Mgr);
131bool ento::shouldRegisterDivZeroChecker(
const CheckerManager &) {
return true; }
133void ento::registerTaintedDivChecker(CheckerManager &Mgr) {
134 Mgr.
getChecker<DivZeroChecker>()->TaintedDivChecker.enable(Mgr);
137bool ento::shouldRegisterTaintedDivChecker(
const CheckerManager &) {
static const Expr * getDenomExpr(const ExplodedNode *N)
BinaryOperatorKind Opcode
This represents one expression.
Stmt - This represents one statement.
bool isScalarType() const
Checker families (where a single backend class implements multiple related frontends) should derive f...
CHECKER * getChecker(AT &&...Args)
If the the singleton instance of a checker class is not yet constructed, then construct it (with the ...
ProgramStatePair assumeDual(ProgramStateRef State, DefinedSVal Cond)
Returns a pair of states (StTrue, StFalse) where the given condition is assumed to be true or false,...
std::optional< T > getLocationAs() const &
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
bool trackExpressionValue(const ExplodedNode *N, const Expr *E, PathSensitiveBugReport &R, TrackingOptions Opts={})
Attempts to add visitors to track expression value back to its point of origin.
const char *const TaintedData
std::vector< SymbolRef > getTaintedSymbols(ProgramStateRef State, const Stmt *S, const LocationContext *LCtx, TaintTagType Kind=TaintTagGeneric)
Returns the tainted Symbols for a given Statement and state.
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
The JSON file list parser is used to communicate input to InstallAPI.