 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
69.2% |
18 / 26 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
92.3% |
24 / 26 |
| |
|
Line Coverage: |
92.5% |
37 / 40 |
| |
 |
|
 |
1 : //=== VLASizeChecker.cpp - Undefined dereference 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 VLASizeChecker, a builtin check in GRExprEngine that
11 : // performs checks for declaration of VLA of undefined or zero size.
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 {
2138: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
23 2138: class VLASizeChecker : public CheckerVisitor<VLASizeChecker> {
24 : BugType *BT_zero;
25 : BugType *BT_undef;
26 :
27 : public:
28 2138: VLASizeChecker() : BT_zero(0), BT_undef(0) {}
29 2138: static void *getTag() { static int tag = 0; return &tag; }
30 : void PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS);
31 : };
32 : } // end anonymous namespace
33 :
34 2138: void clang::RegisterVLASizeChecker(GRExprEngine &Eng) {
35 2138: Eng.registerCheck(new VLASizeChecker());
36 2138: }
37 :
38 2438: void VLASizeChecker::PreVisitDeclStmt(CheckerContext &C, const DeclStmt *DS) {
0: branch 1 not taken
2438: branch 2 taken
39 2438: if (!DS->isSingleDecl())
40 0: return;
41 :
42 2438: const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl());
0: branch 0 not taken
2438: branch 1 taken
43 2438: if (!VD)
44 0: return;
45 :
46 : const VariableArrayType *VLA
47 2438: = C.getASTContext().getAsVariableArrayType(VD->getType());
2392: branch 0 taken
46: branch 1 taken
48 2438: if (!VLA)
49 2392: return;
50 :
51 : // FIXME: Handle multi-dimensional VLAs.
52 46: const Expr* SE = VLA->getSizeExpr();
53 46: const GRState *state = C.getState();
54 46: SVal sizeV = state->getSVal(SE);
55 :
10: branch 1 taken
36: branch 2 taken
56 46: if (sizeV.isUndef()) {
57 : // Generate an error node.
58 10: ExplodedNode *N = C.GenerateSink();
0: branch 0 not taken
10: branch 1 taken
59 10: if (!N)
60 20: return;
61 :
10: branch 0 taken
0: branch 1 not taken
62 10: if (!BT_undef)
63 : BT_undef = new BuiltinBug("Declared variable-length array (VLA) uses a "
64 10: "garbage value as its size");
65 :
66 : EnhancedBugReport *report =
67 10: new EnhancedBugReport(*BT_undef, BT_undef->getName(), N);
68 10: report->addRange(SE->getSourceRange());
69 10: report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, SE);
70 10: C.EmitReport(report);
71 : return;
72 : }
73 :
74 : // Check if the size is zero.
75 36: DefinedOrUnknownSVal sizeD = cast<DefinedOrUnknownSVal>(sizeV);
76 :
77 : const GRState *stateNotZero, *stateZero;
78 36: llvm::tie(stateNotZero, stateZero) = state->Assume(sizeD);
79 :
24: branch 0 taken
12: branch 1 taken
10: branch 2 taken
14: branch 3 taken
80 36: if (stateZero && !stateNotZero) {
81 10: ExplodedNode* N = C.GenerateSink(stateZero);
10: branch 0 taken
0: branch 1 not taken
82 10: if (!BT_zero)
83 : BT_zero = new BuiltinBug("Declared variable-length array (VLA) has zero "
84 10: "size");
85 :
86 : EnhancedBugReport *report =
87 10: new EnhancedBugReport(*BT_zero, BT_zero->getName(), N);
88 10: report->addRange(SE->getSourceRange());
89 10: report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, SE);
90 10: C.EmitReport(report);
91 : return;
92 : }
93 :
94 : // From this point on, assume that the size is not zero.
26: branch 2 taken
10: branch 3 taken
26: branch 5 taken
20: branch 6 taken
95 26: C.addTransition(stateNotZero);
96 0: }
Generated: 2010-02-10 01:31 by zcov