zcov: / lib/Checker/PointerSubChecker.cpp


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


Programs: 1 Runs 2897


       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