zcov: / lib/Checker/DivZeroChecker.cpp


Files: 1 Branches Taken: 66.7% 20 / 30
Generated: 2010-02-10 01:31 Branches Executed: 80.0% 24 / 30
Line Coverage: 75.0% 21 / 28


Programs: 1 Runs 2897


       1                 : //== DivZeroChecker.cpp - Division by zero 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 DivZeroChecker, a builtin check in GRExprEngine that performs
      11                 : // checks for division by zeros.
      12                 : //
      13                 : //===----------------------------------------------------------------------===//
      14                 : 
      15                 : #include "clang/Checker/PathSensitive/CheckerVisitor.h"
      16                 : #include "GRExprEngineInternalChecks.h"
      17                 : 
      18                 : using namespace clang;
      19                 : 
      20                 : namespace {
                     2138: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
      21             2138: class DivZeroChecker : public CheckerVisitor<DivZeroChecker> {
      22                 :   BuiltinBug *BT;
      23                 : public:
      24             2138:   DivZeroChecker() : BT(0) {}  
      25                 :   static void *getTag();
      26                 :   void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
      27                 : };  
      28                 : } // end anonymous namespace
      29                 : 
      30             2138: void clang::RegisterDivZeroChecker(GRExprEngine &Eng) {
      31             2138:   Eng.registerCheck(new DivZeroChecker());
      32             2138: }
      33                 : 
      34             2138: void *DivZeroChecker::getTag() {
      35                 :   static int x;
      36             2138:   return &x;
      37                 : }
      38                 : 
      39                 : void DivZeroChecker::PreVisitBinaryOperator(CheckerContext &C,
      40             3386:                                             const BinaryOperator *B) {
      41             3386:   BinaryOperator::Opcode Op = B->getOpcode();
                     3275: branch 0 taken
                      111: branch 1 taken
                     3265: branch 2 taken
                       10: branch 3 taken
                     3255: branch 4 taken
                       10: branch 5 taken
                     3255: branch 6 taken
                        0: branch 7 not taken
      42             3386:   if (Op != BinaryOperator::Div &&
      43                 :       Op != BinaryOperator::Rem &&
      44                 :       Op != BinaryOperator::DivAssign &&
      45                 :       Op != BinaryOperator::RemAssign)
      46             3255:     return;
      47                 : 
                       59: branch 4 taken
                       72: branch 5 taken
                        0: branch 10 not taken
                       59: branch 11 taken
                       72: branch 12 taken
                       59: branch 13 taken
      48              131:   if (!B->getRHS()->getType()->isIntegerType() ||
      49                 :       !B->getRHS()->getType()->isScalarType())
      50               72:     return;
      51                 : 
      52               59:   SVal Denom = C.getState()->getSVal(B->getRHS());
      53               59:   const DefinedSVal *DV = dyn_cast<DefinedSVal>(&Denom);
      54                 : 
      55                 :   // Divide-by-undefined handled in the generic checking for uses of
      56                 :   // undefined values.
                       10: branch 0 taken
                       49: branch 1 taken
      57               59:   if (!DV)
      58               10:     return;
      59                 : 
      60                 :   // Check for divide by zero.
      61               49:   ConstraintManager &CM = C.getConstraintManager();
      62                 :   const GRState *stateNotZero, *stateZero;
      63               49:   llvm::tie(stateNotZero, stateZero) = CM.AssumeDual(C.getState(), *DV);
      64                 : 
                       20: branch 0 taken
                       29: branch 1 taken
                        0: branch 2 not taken
                       20: branch 3 taken
      65               49:   if (stateZero && !stateNotZero) {
                        0: branch 1 not taken
                        0: branch 2 not taken
      66                0:     if (ExplodedNode *N = C.GenerateSink(stateZero)) {
                        0: branch 0 not taken
                        0: branch 1 not taken
      67                0:       if (!BT)
      68                0:         BT = new BuiltinBug("Division by zero");
      69                 : 
      70                 :       EnhancedBugReport *R = 
      71                0:         new EnhancedBugReport(*BT, BT->getDescription(), N);
      72                 : 
      73                 :       R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
      74                0:                            bugreporter::GetDenomExpr(N));
      75                 : 
      76                0:       C.EmitReport(R);
      77                 :     }
      78                 :     return;
      79                 :   }
      80                 : 
      81                 :   // If we get here, then the denom should not be zero. We abandon the implicit
      82                 :   // zero denom case for now.
                       49: branch 2 taken
                       10: branch 3 taken
      83               49:   C.addTransition(stateNotZero);
      84                0: }

Generated: 2010-02-10 01:31 by zcov