 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
60.0% |
12 / 20 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
90.0% |
18 / 20 |
| |
|
Line Coverage: |
88.2% |
30 / 34 |
| |
 |
|
 |
1 : //=== UndefResultChecker.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 defines UndefResultChecker, a builtin check in GRExprEngine that
11 : // performs checks for undefined results of non-assignment binary operators.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "GRExprEngineInternalChecks.h"
16 : #include "clang/Checker/PathSensitive/CheckerVisitor.h"
17 : #include "clang/Checker/PathSensitive/GRExprEngine.h"
18 : #include "clang/Checker/BugReporter/BugReporter.h"
19 :
20 : using namespace clang;
21 :
22 : namespace {
23 : class UndefResultChecker
2138: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
24 2138: : public CheckerVisitor<UndefResultChecker> {
25 :
26 : BugType *BT;
27 :
28 : public:
29 2138: UndefResultChecker() : BT(0) {}
30 2138: static void *getTag() { static int tag = 0; return &tag; }
31 : void PostVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
32 : };
33 : } // end anonymous namespace
34 :
35 2138: void clang::RegisterUndefResultChecker(GRExprEngine &Eng) {
36 2138: Eng.registerCheck(new UndefResultChecker());
37 2138: }
38 :
39 : void UndefResultChecker::PostVisitBinaryOperator(CheckerContext &C,
40 3317: const BinaryOperator *B) {
41 3317: const GRState *state = C.getState();
24: branch 3 taken
3293: branch 4 taken
42 3317: if (state->getSVal(B).isUndef()) {
43 : // Generate an error node.
44 24: ExplodedNode *N = C.GenerateSink();
0: branch 0 not taken
24: branch 1 taken
45 24: if (!N)
46 0: return;
47 :
24: branch 0 taken
0: branch 1 not taken
48 24: if (!BT)
49 24: BT = new BuiltinBug("Result of operation is garbage or undefined");
50 :
51 24: llvm::SmallString<256> sbuf;
52 24: llvm::raw_svector_ostream OS(sbuf);
53 24: const Expr *Ex = NULL;
54 24: bool isLeft = true;
55 :
11: branch 4 taken
13: branch 5 taken
56 24: if (state->getSVal(B->getLHS()).isUndef()) {
57 11: Ex = B->getLHS()->IgnoreParenCasts();
58 11: isLeft = true;
59 : }
13: branch 4 taken
0: branch 5 not taken
60 13: else if (state->getSVal(B->getRHS()).isUndef()) {
61 13: Ex = B->getRHS()->IgnoreParenCasts();
62 13: isLeft = false;
63 : }
64 :
24: branch 0 taken
0: branch 1 not taken
65 24: if (Ex) {
66 : OS << "The " << (isLeft ? "left" : "right")
67 : << " operand of '"
68 : << BinaryOperator::getOpcodeStr(B->getOpcode())
11: branch 2 taken
13: branch 3 taken
69 24: << "' is a garbage value";
70 : }
71 : else {
72 : // Neither operand was undefined, but the result is undefined.
73 : OS << "The result of the '"
74 : << BinaryOperator::getOpcodeStr(B->getOpcode())
75 0: << "' expression is undefined";
76 : }
77 24: EnhancedBugReport *report = new EnhancedBugReport(*BT, OS.str(), N);
24: branch 0 taken
0: branch 1 not taken
78 24: if (Ex) {
79 24: report->addRange(Ex->getSourceRange());
80 24: report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, Ex);
81 : }
82 : else
83 0: report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, B);
84 24: C.EmitReport(report);
85 : }
86 0: }
Generated: 2010-02-10 01:31 by zcov