https://github.com/capitan-davide updated https://github.com/llvm/llvm-project/pull/176727
>From 5a74b6b6e28685a6ee55bc4baa581828e1fbfbac Mon Sep 17 00:00:00 2001 From: Davide Cunial <[email protected]> Date: Mon, 19 Jan 2026 10:35:45 +0000 Subject: [PATCH] [clang][analyzer] Add 'Strict' option to 'core.DivideZero' checker With the option 'Strict' the checker warns every time the denominator of a division is potentially zero. --- .../clang/StaticAnalyzer/Checkers/Checkers.td | 8 ++++++ .../Checkers/DivZeroChecker.cpp | 25 +++++++++++++------ clang/test/Analysis/analyzer-config.c | 1 + 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index e1662e0792e69..116b51eb655e0 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -214,6 +214,14 @@ def VLASizeChecker : Checker<"VLASize">, def DivZeroChecker : Checker<"DivideZero">, HelpText<"Check for division by zero">, + CheckerOptions<[ + CmdLineOption<Boolean, + "Strict", + "Warn on all potential divisions by zero i.e., if zero " + "falls within the range of possible divisor values.", + "false", + InAlpha>, + ]>, Documentation<HasDocumentation>; def UndefResultChecker : Checker<"UndefinedBinaryOperatorResult">, diff --git a/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp index ab90615f63182..777576153fab2 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp @@ -13,6 +13,7 @@ #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Checkers/Taint.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -42,6 +43,11 @@ class DivZeroChecker : public CheckerFamily<check::PreStmt<BinaryOperator>> { /// Identifies this checker family for debugging purposes. StringRef getDebugTag() const override { return "DivZeroChecker"; } + +public: + /// In strict mode, the checker warns about all potential divisions by zero + /// i.e., if zero falls within the range of possible divisor values. + bool Strict = true; }; } // end anonymous namespace @@ -73,7 +79,7 @@ void DivZeroChecker::reportTaintBug( auto R = std::make_unique<PathSensitiveBugReport>(TaintedDivChecker, Msg, N); bugreporter::trackExpressionValue(N, getDenomExpr(N), *R); - for (auto Sym : TaintedSyms) + for (const auto *Sym : TaintedSyms) R->markInteresting(Sym); C.emitReport(std::move(R)); } @@ -82,10 +88,7 @@ void DivZeroChecker::reportTaintBug( void DivZeroChecker::checkPreStmt(const BinaryOperator *B, CheckerContext &C) const { BinaryOperator::Opcode Op = B->getOpcode(); - if (Op != BO_Div && - Op != BO_Rem && - Op != BO_DivAssign && - Op != BO_RemAssign) + if (Op != BO_Div && Op != BO_Rem && Op != BO_DivAssign && Op != BO_RemAssign) return; if (!B->getRHS()->getType()->isScalarType()) @@ -112,11 +115,13 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B, if ((stateNotZero && stateZero)) { std::vector<SymbolRef> taintedSyms = getTaintedSymbols(C.getState(), *DV); - if (!taintedSyms.empty()) { + if (Strict) { + reportBug("Potential division by zero", stateZero, C); + } else if (!taintedSyms.empty()) { reportTaintBug("Division by a tainted value, possibly zero", stateZero, C, taintedSyms); - // Fallthrough to continue analysis in case of non-zero denominator. } + // Fallthrough to continue analysis in case of non-zero denominator. } // If we get here, then the denom should not be zero. We abandon the implicit @@ -125,7 +130,11 @@ void DivZeroChecker::checkPreStmt(const BinaryOperator *B, } void ento::registerDivZeroChecker(CheckerManager &Mgr) { - Mgr.getChecker<DivZeroChecker>()->DivideZeroChecker.enable(Mgr); + auto *Chk = Mgr.getChecker<DivZeroChecker>(); + CheckerNameRef ChkName = Mgr.getCurrentCheckerName(); + Chk->Strict = + Mgr.getAnalyzerOptions().getcheckerBooleanOption(ChkName, "Strict"); + Chk->DivideZeroChecker.enable(Mgr); } bool ento::shouldRegisterDivZeroChecker(const CheckerManager &) { return true; } diff --git a/clang/test/Analysis/analyzer-config.c b/clang/test/Analysis/analyzer-config.c index 4e1f5336a9040..37cc514216e12 100644 --- a/clang/test/Analysis/analyzer-config.c +++ b/clang/test/Analysis/analyzer-config.c @@ -38,6 +38,7 @@ // CHECK-NEXT: core.CallAndMessage:NilReceiver = true // CHECK-NEXT: core.CallAndMessage:ParameterCount = true // CHECK-NEXT: core.CallAndMessage:UndefReceiver = true +// CHECK-NEXT: core.DivideZero:Strict = false // CHECK-NEXT: cplusplus.Move:WarnOn = KnownsAndLocals // CHECK-NEXT: cplusplus.SmartPtrModeling:ModelSmartPtrDereference = false // CHECK-NEXT: crosscheck-with-z3 = false _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
