20 #include "llvm/ADT/FoldingSet.h" 22 using namespace clang;
35 : ZeroSymbol(S), BlockID(B), SFC(SFC) {}
40 return BlockID == X.BlockID && SFC == X.SFC && ZeroSymbol == X.ZeroSymbol;
44 if (BlockID != X.BlockID)
45 return BlockID < X.BlockID;
48 return ZeroSymbol < X.ZeroSymbol;
51 void Profile(llvm::FoldingSetNodeID &
ID)
const {
52 ID.AddInteger(BlockID);
54 ID.AddPointer(ZeroSymbol);
66 : ZeroSymbol(ZeroSymbol), SFC(SFC), Satisfied(
false) {}
68 void Profile(llvm::FoldingSetNodeID &ID)
const override {
73 std::shared_ptr<PathDiagnosticPiece> VisitNode(
const ExplodedNode *Succ,
79 class TestAfterDivZeroChecker
80 :
public Checker<check::PreStmt<BinaryOperator>, check::BranchCondition,
82 mutable std::unique_ptr<BuiltinBug> DivZeroBug;
97 std::shared_ptr<PathDiagnosticPiece>
103 const Expr *E =
nullptr;
108 if (Op == BO_Div || Op == BO_Rem || Op == BO_DivAssign ||
109 Op == BO_RemAssign) {
130 return std::make_shared<PathDiagnosticEventPiece>(
131 L,
"Division with compared value made here");
158 bool TestAfterDivZeroChecker::hasDivZeroMap(
SVal Var,
165 return C.
getState()->contains<DivZeroMap>(ZS);
171 DivZeroBug.reset(
new BuiltinBug(
this,
"Division by zero"));
173 auto R = llvm::make_unique<BugReport>(
174 *DivZeroBug,
"Value being compared against zero has already been used " 178 R->addVisitor(llvm::make_unique<DivisionBRVisitor>(Val.
getAsSymbol(),
184 void TestAfterDivZeroChecker::checkEndFunction(
CheckerContext &C)
const {
187 DivZeroMapTy DivZeroes = State->get<DivZeroMap>();
188 if (DivZeroes.isEmpty())
191 DivZeroMapTy::Factory &F = State->get_context<DivZeroMap>();
197 DivZeroes = F.remove(DivZeroes, ZS);
202 void TestAfterDivZeroChecker::checkPreStmt(
const BinaryOperator *B,
205 if (Op == BO_Div || Op == BO_Rem || Op == BO_DivAssign ||
206 Op == BO_RemAssign) {
214 void TestAfterDivZeroChecker::checkBranchCondition(
const Stmt *Condition,
216 if (
const BinaryOperator *B = dyn_cast<BinaryOperator>(Condition)) {
225 if (!IntLiteral || IntLiteral->
getValue() != 0)
229 if (hasDivZeroMap(Val, C))
232 }
else if (
const UnaryOperator *U = dyn_cast<UnaryOperator>(Condition)) {
233 if (U->getOpcode() == UO_LNot) {
236 dyn_cast<ImplicitCastExpr>(U->getSubExpr()))
237 Val = C.
getSVal(I->getSubExpr());
239 if (hasDivZeroMap(Val, C))
242 Val = C.
getSVal(U->getSubExpr());
243 if (hasDivZeroMap(Val, C))
248 dyn_cast<ImplicitCastExpr>(Condition)) {
251 if (hasDivZeroMap(Val, C))
256 if (hasDivZeroMap(Val, C))
virtual ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond, bool Assumption)=0
ExplodedNode * generateErrorNode(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generate a transition to a node that will be used to report an error.
bool operator==(CanQual< T > x, CanQual< U > y)
Stmt - This represents one statement.
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
const ProgramStateRef & getState() const
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.
#define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem)
Declares an immutable set of type NameTy, suitable for placement into the ProgramState.
This class provides a convenience implementation for clone() using the Curiously-Recurring Template P...
Optional< T > getLocationAs() const LLVM_LVALUE_FUNCTION
const LocationContext * getLocationContext() const
A builtin binary operation expression such as "x + y" or "x <= y".
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
Expr - This represents one expression.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
ConstraintManager & getConstraintManager()
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
FullSourceLoc asLocation() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
unsigned getBlockID() const
Get the blockID.
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
llvm::APInt getValue() const
const StackFrameContext * getStackFrame() const
const ProgramStateRef & getState() const
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
const StackFrameContext * getStackFrame() const
This class provides an interface through which checkers can create individual bug reports...
static bool isComparisonOp(Opcode Opc)
SourceManager & getSourceManager()