 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
53.8% |
14 / 26 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
92.3% |
24 / 26 |
| |
|
Line Coverage: |
97.8% |
45 / 46 |
| |
 |
|
 |
1 : //=== UndefBranchChecker.cpp -----------------------------------*- 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 file defines UndefBranchChecker, which checks for undefined branch
11 : // condition.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "GRExprEngineInternalChecks.h"
16 : #include "clang/Checker/PathSensitive/Checker.h"
17 :
18 : using namespace clang;
19 :
20 : namespace {
21 :
2138: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
22 2138: class UndefBranchChecker : public Checker {
23 : BuiltinBug *BT;
24 :
25 : struct FindUndefExpr {
26 : GRStateManager& VM;
27 : const GRState* St;
28 :
29 30: FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}
30 :
31 40: Expr* FindExpr(Expr* Ex) {
0: branch 1 not taken
40: branch 2 taken
32 40: if (!MatchesCriteria(Ex))
33 0: return 0;
34 :
10: branch 4 taken
30: branch 5 taken
35 40: for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
10: branch 2 taken
0: branch 3 not taken
36 10: if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
37 10: Expr* E2 = FindExpr(ExI);
10: branch 0 taken
0: branch 1 not taken
38 10: if (E2) return E2;
39 : }
40 :
41 30: return Ex;
42 : }
43 :
44 40: bool MatchesCriteria(Expr* Ex) { return St->getSVal(Ex).isUndef(); }
45 : };
46 :
47 : public:
48 2138: UndefBranchChecker() : BT(0) {}
49 : static void *getTag();
50 : void VisitBranchCondition(GRBranchNodeBuilder &Builder, GRExprEngine &Eng,
51 : Stmt *Condition, void *tag);
52 : };
53 :
54 : }
55 :
56 2138: void clang::RegisterUndefBranchChecker(GRExprEngine &Eng) {
57 2138: Eng.registerCheck(new UndefBranchChecker());
58 2138: }
59 :
60 2138: void *UndefBranchChecker::getTag() {
61 : static int x;
62 2138: return &x;
63 : }
64 :
65 : void UndefBranchChecker::VisitBranchCondition(GRBranchNodeBuilder &Builder,
66 : GRExprEngine &Eng,
67 2248: Stmt *Condition, void *tag) {
68 2248: const GRState *state = Builder.getState();
69 2248: SVal X = state->getSVal(Condition);
30: branch 1 taken
2218: branch 2 taken
70 2248: if (X.isUndef()) {
71 30: ExplodedNode *N = Builder.generateNode(state, true);
30: branch 0 taken
0: branch 1 not taken
72 30: if (N) {
73 30: N->markAsSink();
30: branch 0 taken
0: branch 1 not taken
74 30: if (!BT)
75 30: BT = new BuiltinBug("Branch condition evaluates to a garbage value");
76 :
77 : // What's going on here: we want to highlight the subexpression of the
78 : // condition that is the most likely source of the "uninitialized
79 : // branch condition." We do a recursive walk of the condition's
80 : // subexpressions and roughly look for the most nested subexpression
81 : // that binds to Undefined. We then highlight that expression's range.
82 30: BlockEdge B = cast<BlockEdge>(N->getLocation());
83 30: Expr* Ex = cast<Expr>(B.getSrc()->getTerminatorCondition());
0: branch 0 not taken
30: branch 1 taken
84 30: assert (Ex && "Block must have a terminator.");
85 :
86 : // Get the predecessor node and check if is a PostStmt with the Stmt
87 : // being the terminator condition. We want to inspect the state
88 : // of that node instead because it will contain main information about
89 : // the subexpressions.
0: branch 1 not taken
30: branch 2 taken
90 30: assert (!N->pred_empty());
91 :
92 : // Note: any predecessor will do. They should have identical state,
93 : // since all the BlockEdge did was act as an error sink since the value
94 : // had to already be undefined.
95 30: ExplodedNode *PrevN = *N->pred_begin();
96 30: ProgramPoint P = PrevN->getLocation();
97 30: const GRState* St = N->getState();
98 :
30: branch 1 taken
0: branch 2 not taken
99 30: if (PostStmt* PS = dyn_cast<PostStmt>(&P))
30: branch 1 taken
0: branch 2 not taken
100 30: if (PS->getStmt() == Ex)
101 30: St = PrevN->getState();
102 :
103 30: FindUndefExpr FindIt(Eng.getStateManager(), St);
104 30: Ex = FindIt.FindExpr(Ex);
105 :
106 : // Emit the bug report.
107 30: EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getDescription(),N);
108 30: R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, Ex);
109 30: R->addRange(Ex->getSourceRange());
110 :
111 30: Eng.getBugReporter().EmitReport(R);
112 : }
113 :
114 30: Builder.markInfeasible(true);
115 30: Builder.markInfeasible(false);
116 2248: }
117 2248: }
Generated: 2010-02-10 01:31 by zcov