 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
73.1% |
19 / 26 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
92.3% |
24 / 26 |
| |
|
Line Coverage: |
100.0% |
28 / 28 |
| |
 |
|
 |
1 : //=== PointerSubChecker.cpp - Pointer subtraction 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 PointerSubChecker, a builtin checker that checks for
11 : // pointer subtractions on two pointers pointing to different memory chunks.
12 : // This check corresponds to CWE-469.
13 : //
14 : //===----------------------------------------------------------------------===//
15 :
16 : #include "clang/Checker/PathSensitive/CheckerVisitor.h"
17 : #include "GRExprEngineInternalChecks.h"
18 :
19 : using namespace clang;
20 :
21 : namespace {
22 : class PointerSubChecker
1845: branch 1 taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
23 1845: : public CheckerVisitor<PointerSubChecker> {
24 : BuiltinBug *BT;
25 : public:
26 1845: PointerSubChecker() : BT(0) {}
27 : static void *getTag();
28 : void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
29 : };
30 : }
31 :
32 1845: void *PointerSubChecker::getTag() {
33 : static int x;
34 1845: return &x;
35 : }
36 :
37 : void PointerSubChecker::PreVisitBinaryOperator(CheckerContext &C,
38 3124: const BinaryOperator *B) {
39 : // When doing pointer subtraction, if the two pointers do not point to the
40 : // same memory chunk, emit a warning.
3078: branch 1 taken
46: branch 2 taken
41 3124: if (B->getOpcode() != BinaryOperator::Sub)
42 3078: return;
43 :
44 46: const GRState *state = C.getState();
45 46: SVal LV = state->getSVal(B->getLHS());
46 46: SVal RV = state->getSVal(B->getRHS());
47 :
48 46: const MemRegion *LR = LV.getAsRegion();
49 46: const MemRegion *RR = RV.getAsRegion();
50 :
8: branch 0 taken
38: branch 1 taken
0: branch 2 not taken
8: branch 3 taken
51 46: if (!(LR && RR))
52 44: return;
53 :
54 8: const MemRegion *BaseLR = LR->getBaseRegion();
55 8: const MemRegion *BaseRR = RR->getBaseRegion();
56 :
2: branch 0 taken
6: branch 1 taken
57 8: if (BaseLR == BaseRR)
58 : return;
59 :
60 : // Allow arithmetic on different symbolic regions.
2: branch 1 taken
4: branch 2 taken
0: branch 4 not taken
2: branch 5 taken
4: branch 6 taken
2: branch 7 taken
61 6: if (isa<SymbolicRegion>(BaseLR) || isa<SymbolicRegion>(BaseRR))
62 : return;
63 :
2: branch 1 taken
0: branch 2 not taken
64 2: if (ExplodedNode *N = C.GenerateNode()) {
2: branch 0 taken
0: branch 1 not taken
65 2: if (!BT)
66 : BT = new BuiltinBug("Pointer subtraction",
67 : "Subtraction of two pointers that do not point to "
68 2: "the same memory chunk may cause incorrect result.");
69 2: RangedBugReport *R = new RangedBugReport(*BT, BT->getDescription(), N);
70 2: R->addRange(B->getSourceRange());
71 2: C.EmitReport(R);
2: branch 1 taken
44: branch 2 taken
2: branch 4 taken
44: branch 5 taken
72 46: }
73 : }
74 :
75 1845: void clang::RegisterPointerSubChecker(GRExprEngine &Eng) {
76 1845: Eng.registerCheck(new PointerSubChecker());
77 1845: }
Generated: 2010-02-10 01:31 by zcov