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 {
79 class TestAfterDivZeroChecker
80 :
public Checker<check::PreStmt<BinaryOperator>, check::BranchCondition,
82 mutable std::unique_ptr<BuiltinBug> DivZeroBug;
104 const Expr *
E =
nullptr;
109 if (Op == BO_Div || Op == BO_Rem || Op == BO_DivAssign ||
110 Op == BO_RemAssign) {
119 SVal S = State->getSVal(E, Succ->getLocationContext());
120 if (ZeroSymbol == S.
getAsSymbol() && SFC == Succ->getStackFrame()) {
132 L,
"Division with compared value made here");
159 bool TestAfterDivZeroChecker::hasDivZeroMap(
SVal Var,
166 return C.
getState()->contains<DivZeroMap>(ZS);
172 DivZeroBug.reset(
new BuiltinBug(
this,
"Division by zero"));
174 auto R = llvm::make_unique<BugReport>(
175 *DivZeroBug,
"Value being compared against zero has already been used "
179 R->addVisitor(llvm::make_unique<DivisionBRVisitor>(Val.
getAsSymbol(),
185 void TestAfterDivZeroChecker::checkEndFunction(
CheckerContext &C)
const {
188 DivZeroMapTy DivZeroes = State->get<DivZeroMap>();
189 if (DivZeroes.isEmpty())
192 DivZeroMapTy::Factory &F = State->get_context<DivZeroMap>();
198 DivZeroes = F.remove(DivZeroes, ZS);
203 void TestAfterDivZeroChecker::checkPreStmt(
const BinaryOperator *B,
206 if (Op == BO_Div || Op == BO_Rem || Op == BO_DivAssign ||
207 Op == BO_RemAssign) {
215 void TestAfterDivZeroChecker::checkBranchCondition(
const Stmt *Condition,
217 if (
const BinaryOperator *B = dyn_cast<BinaryOperator>(Condition)) {
226 if (!IntLiteral || IntLiteral->
getValue() != 0)
230 if (hasDivZeroMap(Val, C))
233 }
else if (
const UnaryOperator *U = dyn_cast<UnaryOperator>(Condition)) {
234 if (U->getOpcode() == UO_LNot) {
237 dyn_cast<ImplicitCastExpr>(U->getSubExpr()))
240 if (hasDivZeroMap(Val, C))
243 Val = C.
getSVal(U->getSubExpr());
244 if (hasDivZeroMap(Val, C))
249 dyn_cast<ImplicitCastExpr>(Condition)) {
252 if (hasDivZeroMap(Val, C))
257 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)
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
#define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem)
Declares an immutable set of type NameTy, suitable for placement into the ProgramState.
FullSourceLoc asLocation() const
This class provides a convenience implementation for clone() using the Curiously-Recurring Template P...
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.
detail::InMemoryDirectory::const_iterator I
llvm::APInt getValue() const
Expr - This represents one expression.
const ProgramStateRef & getState() const
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
ConstraintManager & getConstraintManager()
void emitReport(std::unique_ptr< BugReport > R)
Emit the diagnostics report.
CHECKER * registerChecker()
Used to register checkers.
bool isValid() const
Return true if this is a valid SourceLocation object.
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx)
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
const StackFrameContext * getStackFrame() const
detail::InMemoryDirectory::const_iterator E
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
unsigned getBlockID() const
Get the blockID.
SymbolRef getAsSymbol(bool IncludeBaseRegions=false) const
If this SVal wraps a symbol return that SymbolRef.
This class provides an interface through which checkers can create individual bug reports...
static bool isComparisonOp(Opcode Opc)
SVal getSVal(const Stmt *S) const
Get the value of arbitrary expressions at this point in the path.