 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
66.7% |
20 / 30 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
80.0% |
24 / 30 |
| |
|
Line Coverage: |
75.0% |
21 / 28 |
| |
 |
|
 |
1 : //== DivZeroChecker.cpp - Division by zero checker --------------*- C++ -*--==//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This defines DivZeroChecker, a builtin check in GRExprEngine that performs
11 : // checks for division by zeros.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "clang/Checker/PathSensitive/CheckerVisitor.h"
16 : #include "GRExprEngineInternalChecks.h"
17 :
18 : using namespace clang;
19 :
20 : namespace {
2138: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
21 2138: class DivZeroChecker : public CheckerVisitor<DivZeroChecker> {
22 : BuiltinBug *BT;
23 : public:
24 2138: DivZeroChecker() : BT(0) {}
25 : static void *getTag();
26 : void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
27 : };
28 : } // end anonymous namespace
29 :
30 2138: void clang::RegisterDivZeroChecker(GRExprEngine &Eng) {
31 2138: Eng.registerCheck(new DivZeroChecker());
32 2138: }
33 :
34 2138: void *DivZeroChecker::getTag() {
35 : static int x;
36 2138: return &x;
37 : }
38 :
39 : void DivZeroChecker::PreVisitBinaryOperator(CheckerContext &C,
40 3386: const BinaryOperator *B) {
41 3386: BinaryOperator::Opcode Op = B->getOpcode();
3275: branch 0 taken
111: branch 1 taken
3265: branch 2 taken
10: branch 3 taken
3255: branch 4 taken
10: branch 5 taken
3255: branch 6 taken
0: branch 7 not taken
42 3386: if (Op != BinaryOperator::Div &&
43 : Op != BinaryOperator::Rem &&
44 : Op != BinaryOperator::DivAssign &&
45 : Op != BinaryOperator::RemAssign)
46 3255: return;
47 :
59: branch 4 taken
72: branch 5 taken
0: branch 10 not taken
59: branch 11 taken
72: branch 12 taken
59: branch 13 taken
48 131: if (!B->getRHS()->getType()->isIntegerType() ||
49 : !B->getRHS()->getType()->isScalarType())
50 72: return;
51 :
52 59: SVal Denom = C.getState()->getSVal(B->getRHS());
53 59: const DefinedSVal *DV = dyn_cast<DefinedSVal>(&Denom);
54 :
55 : // Divide-by-undefined handled in the generic checking for uses of
56 : // undefined values.
10: branch 0 taken
49: branch 1 taken
57 59: if (!DV)
58 10: return;
59 :
60 : // Check for divide by zero.
61 49: ConstraintManager &CM = C.getConstraintManager();
62 : const GRState *stateNotZero, *stateZero;
63 49: llvm::tie(stateNotZero, stateZero) = CM.AssumeDual(C.getState(), *DV);
64 :
20: branch 0 taken
29: branch 1 taken
0: branch 2 not taken
20: branch 3 taken
65 49: if (stateZero && !stateNotZero) {
0: branch 1 not taken
0: branch 2 not taken
66 0: if (ExplodedNode *N = C.GenerateSink(stateZero)) {
0: branch 0 not taken
0: branch 1 not taken
67 0: if (!BT)
68 0: BT = new BuiltinBug("Division by zero");
69 :
70 : EnhancedBugReport *R =
71 0: new EnhancedBugReport(*BT, BT->getDescription(), N);
72 :
73 : R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
74 0: bugreporter::GetDenomExpr(N));
75 :
76 0: C.EmitReport(R);
77 : }
78 : return;
79 : }
80 :
81 : // If we get here, then the denom should not be zero. We abandon the implicit
82 : // zero denom case for now.
49: branch 2 taken
10: branch 3 taken
83 49: C.addTransition(stateNotZero);
84 0: }
Generated: 2010-02-10 01:31 by zcov