zcov: / lib/Checker/PointerArithChecker.cpp


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


Programs: 1 Runs 2897


       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