 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
78.1% |
25 / 32 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
93.8% |
30 / 32 |
| |
|
Line Coverage: |
100.0% |
24 / 24 |
| |
 |
|
 |
1 : //=== PointerArithChecker.cpp - Pointer arithmetic 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 files defines PointerArithChecker, a builtin checker that checks for
11 : // pointer arithmetic on locations other than array elements.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "clang/Checker/PathSensitive/CheckerVisitor.h"
16 : #include "GRExprEngineInternalChecks.h"
17 :
18 : using namespace clang;
19 :
20 : namespace {
21 : class PointerArithChecker
1845: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
22 1845: : public CheckerVisitor<PointerArithChecker> {
23 : BuiltinBug *BT;
24 : public:
25 1845: PointerArithChecker() : BT(0) {}
26 : static void *getTag();
27 : void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
28 : };
29 : }
30 :
31 1845: void *PointerArithChecker::getTag() {
32 : static int x;
33 1845: return &x;
34 : }
35 :
36 : void PointerArithChecker::PreVisitBinaryOperator(CheckerContext &C,
37 3124: const BinaryOperator *B) {
3078: branch 1 taken
46: branch 2 taken
2924: branch 4 taken
154: branch 5 taken
2924: branch 6 taken
200: branch 7 taken
38 3124: if (B->getOpcode() != BinaryOperator::Sub &&
39 : B->getOpcode() != BinaryOperator::Add)
40 2924: return;
41 :
42 200: const GRState *state = C.getState();
43 200: SVal LV = state->getSVal(B->getLHS());
44 200: SVal RV = state->getSVal(B->getRHS());
45 :
46 200: const MemRegion *LR = LV.getAsRegion();
47 :
60: branch 0 taken
140: branch 1 taken
30: branch 3 taken
30: branch 4 taken
170: branch 5 taken
30: branch 6 taken
48 200: if (!LR || !RV.isConstant())
49 170: return;
50 :
51 : // If pointer arithmetic is done on variables of non-array type, this often
52 : // means behavior rely on memory organization, which is dangerous.
28: branch 1 taken
2: branch 2 taken
28: branch 4 taken
0: branch 5 not taken
0: branch 7 not taken
28: branch 8 taken
2: branch 9 taken
28: branch 10 taken
53 30: if (isa<VarRegion>(LR) || isa<CodeTextRegion>(LR) ||
54 : isa<CompoundLiteralRegion>(LR)) {
55 :
2: branch 1 taken
0: branch 2 not taken
56 2: if (ExplodedNode *N = C.GenerateNode()) {
2: branch 0 taken
0: branch 1 not taken
57 2: if (!BT)
58 : BT = new BuiltinBug("Dangerous pointer arithmetic",
59 : "Pointer arithmetic done on non-array variables "
60 : "means reliance on memory layout, which is "
61 2: "dangerous.");
62 2: RangedBugReport *R = new RangedBugReport(*BT, BT->getDescription(), N);
63 2: R->addRange(B->getSourceRange());
64 2: C.EmitReport(R);
65 : }
30: branch 1 taken
170: branch 2 taken
30: branch 4 taken
170: branch 5 taken
66 200: }
67 : }
68 :
69 1845: void clang::RegisterPointerArithChecker(GRExprEngine &Eng) {
70 1845: Eng.registerCheck(new PointerArithChecker());
71 1845: }
Generated: 2010-02-10 01:31 by zcov