zcov: / lib/Checker/SValuator.cpp


Files: 1 Branches Taken: 78.3% 83 / 106
Generated: 2010-02-10 01:31 Branches Executed: 90.6% 96 / 106
Line Coverage: 90.6% 48 / 53


Programs: 1 Runs 2897


       1                 : // SValuator.cpp - Basic class for all SValuator implementations --*- 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 file defines SValuator, the base class for all (complete) SValuator
      11                 : //  implementations.
      12                 : //
      13                 : //===----------------------------------------------------------------------===//
      14                 : 
      15                 : #include "clang/Checker/PathSensitive/SValuator.h"
      16                 : #include "clang/Checker/PathSensitive/GRState.h"
      17                 : 
      18                 : using namespace clang;
      19                 : 
      20                 : 
      21                 : SVal SValuator::EvalBinOp(const GRState *ST, BinaryOperator::Opcode Op,
      22             3362:                           SVal L, SVal R, QualType T) {
      23                 : 
                     3351: branch 1 taken
                       11: branch 2 taken
                       13: branch 4 taken
                     3338: branch 5 taken
                       24: branch 6 taken
                     3338: branch 7 taken
      24             3362:   if (L.isUndef() || R.isUndef())
      25               24:     return UndefinedVal();
      26                 : 
                     3103: branch 1 taken
                      235: branch 2 taken
                       20: branch 4 taken
                     3083: branch 5 taken
                      255: branch 6 taken
                     3083: branch 7 taken
      27             3338:   if (L.isUnknown() || R.isUnknown())
      28              255:     return UnknownVal();
      29                 : 
                      751: branch 1 taken
                     2332: branch 2 taken
      30             3083:   if (isa<Loc>(L)) {
                      509: branch 1 taken
                      242: branch 2 taken
      31              751:     if (isa<Loc>(R))
      32              509:       return EvalBinOpLL(Op, cast<Loc>(L), cast<Loc>(R), T);
      33                 : 
      34              242:     return EvalBinOpLN(ST, Op, cast<Loc>(L), cast<NonLoc>(R), T);
      35                 :   }
      36                 : 
                        0: branch 1 not taken
                     2332: branch 2 taken
      37             2332:   if (isa<Loc>(R)) {
      38                 :     // Support pointer arithmetic where the increment/decrement operand
      39                 :     // is on the left and the pointer on the right.
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 2 not taken
                        0: branch 3 not taken
      40                0:     assert(Op == BinaryOperator::Add || Op == BinaryOperator::Sub);
      41                 : 
      42                 :     // Commute the operands.
      43                0:     return EvalBinOpLN(ST, Op, cast<Loc>(R), cast<NonLoc>(L), T);
      44                 :   }
      45                 : 
      46             2332:   return EvalBinOpNN(ST, Op, cast<NonLoc>(L), cast<NonLoc>(R), T);
      47                 : }
      48                 : 
      49                 : DefinedOrUnknownSVal SValuator::EvalEQ(const GRState *ST,
      50                 :                                        DefinedOrUnknownSVal L,
      51              301:                                        DefinedOrUnknownSVal R) {
      52                 :   return cast<DefinedOrUnknownSVal>(EvalBinOp(ST, BinaryOperator::EQ, L, R,
      53              301:                                               ValMgr.getContext().IntTy));
      54                 : }
      55                 : 
      56             5360: SVal SValuator::EvalCast(SVal val, QualType castTy, QualType originalTy) {
                     5061: branch 1 taken
                      299: branch 2 taken
                      312: branch 4 taken
                     4749: branch 5 taken
                      611: branch 6 taken
                     4749: branch 7 taken
      57             5360:   if (val.isUnknownOrUndef() || castTy == originalTy)
      58              611:     return val;
      59                 : 
      60             4749:   ASTContext &C = ValMgr.getContext();
      61                 : 
      62                 :   // For const casts, just propagate the value.
                     4749: branch 2 taken
                        0: branch 3 not taken
                     4747: branch 6 taken
                        2: branch 7 taken
                     4747: branch 8 taken
                        2: branch 9 taken
      63             4749:   if (!castTy->isVariableArrayType() && !originalTy->isVariableArrayType())
                       64: branch 1 taken
                     4683: branch 2 taken
      64             4747:     if (C.hasSameUnqualifiedType(castTy, originalTy))
      65               64:       return val;
      66                 : 
      67                 :   // Check for casts to real or complex numbers.  We don't handle these at all
      68                 :   // right now.
                     4583: branch 2 taken
                      102: branch 3 taken
                        0: branch 6 not taken
                     4583: branch 7 taken
                      102: branch 8 taken
                     4583: branch 9 taken
      69             4685:   if (castTy->isFloatingType() || castTy->isAnyComplexType())
      70              102:     return UnknownVal();
      71                 :   
      72                 :   // Check for casts from integers to integers.
                     1304: branch 2 taken
                     3279: branch 3 taken
                     1210: branch 6 taken
                       94: branch 7 taken
                     1210: branch 8 taken
                     3373: branch 9 taken
      73             4583:   if (castTy->isIntegerType() && originalTy->isIntegerType())
      74             1210:     return EvalCastNL(cast<NonLoc>(val), castTy);
      75                 : 
      76                 :   // Check for casts from pointers to integers.
                       94: branch 2 taken
                     3279: branch 3 taken
                       94: branch 5 taken
                        0: branch 6 not taken
                       94: branch 7 taken
                     3279: branch 8 taken
      77             3373:   if (castTy->isIntegerType() && Loc::IsLocType(originalTy))
      78               94:     return EvalCastL(cast<Loc>(val), castTy);
      79                 : 
      80                 :   // Check for casts from integers to pointers.
                     3279: branch 1 taken
                        0: branch 2 not taken
                      937: branch 5 taken
                     2342: branch 6 taken
                      937: branch 7 taken
                     2342: branch 8 taken
      81             3279:   if (Loc::IsLocType(castTy) && originalTy->isIntegerType()) {
                       24: branch 1 taken
                      913: branch 2 taken
      82              937:     if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) {
                       24: branch 3 taken
                        0: branch 4 not taken
      83               24:       if (const MemRegion *R = LV->getLoc().getAsRegion()) {
      84               24:         StoreManager &storeMgr = ValMgr.getStateManager().getStoreManager();
      85               24:         R = storeMgr.CastRegion(R, castTy);
                       24: branch 0 taken
                        0: branch 1 not taken
                        0: branch 4 not taken
                       24: branch 5 taken
                       24: branch 7 taken
                        0: branch 8 not taken
      86               24:         return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
      87                 :       }
      88                0:       return LV->getLoc();
      89                 :     }
      90              913:     goto DispatchCast;
      91                 :   }
      92                 : 
      93                 :   // Just pass through function and block pointers.
                     2324: branch 2 taken
                       18: branch 3 taken
                       42: branch 6 taken
                     2282: branch 7 taken
                       60: branch 8 taken
                     2282: branch 9 taken
      94             2342:   if (originalTy->isBlockPointerType() || originalTy->isFunctionPointerType()) {
                        0: branch 1 not taken
                       60: branch 2 taken
      95               60:     assert(Loc::IsLocType(castTy));
      96               60:     return val;
      97                 :   }
      98                 : 
      99                 :   // Check for casts from array type to another type.
                      469: branch 2 taken
                     1813: branch 3 taken
     100             2282:   if (originalTy->isArrayType()) {
     101                 :     // We will always decay to a pointer.
     102              469:     val = ValMgr.getStateManager().ArrayToPointer(cast<Loc>(val));
     103                 : 
     104                 :     // Are we casting from an array to a pointer?  If so just pass on
     105                 :     // the decayed value.
                      469: branch 2 taken
                        0: branch 3 not taken
     106              469:     if (castTy->isPointerType())
     107              469:       return val;
     108                 : 
     109                 :     // Are we casting from an array to an integer?  If so, cast the decayed
     110                 :     // pointer value to an integer.
                        0: branch 2 not taken
                        0: branch 3 not taken
     111                0:     assert(castTy->isIntegerType());
     112                 : 
     113                 :     // FIXME: Keep these here for now in case we decide soon that we
     114                 :     // need the original decayed type.
     115                 :     //    QualType elemTy = cast<ArrayType>(originalTy)->getElementType();
     116                 :     //    QualType pointerTy = C.getPointerType(elemTy);
     117                0:     return EvalCastL(cast<Loc>(val), castTy);
     118                 :   }
     119                 : 
     120                 :   // Check for casts from a region to a specific type.
                     1621: branch 1 taken
                      192: branch 2 taken
     121             1813:   if (const MemRegion *R = val.getAsRegion()) {
     122                 :     // FIXME: We should handle the case where we strip off view layers to get
     123                 :     //  to a desugared type.
     124                 : 
                        0: branch 1 not taken
                     1621: branch 2 taken
     125             1621:     assert(Loc::IsLocType(castTy));
     126                 :     // We get a symbolic function pointer for a dereference of a function
     127                 :     // pointer, but it is of function type. Example:
     128                 : 
     129                 :     //  struct FPRec {
     130                 :     //    void (*my_func)(int * x);
     131                 :     //  };
     132                 :     //
     133                 :     //  int bar(int x);
     134                 :     //
     135                 :     //  int f1_a(struct FPRec* foo) {
     136                 :     //    int x;
     137                 :     //    (*foo->my_func)(&x);
     138                 :     //    return bar(x)+1; // no-warning
     139                 :     //  }
     140                 : 
     141                 :     assert(Loc::IsLocType(originalTy) || originalTy->isFunctionType() ||
                        0: branch 1 not taken
                     1621: branch 2 taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                        0: branch 9 not taken
                        0: branch 10 not taken
     142             1621:            originalTy->isBlockPointerType());
     143                 : 
     144             1621:     StoreManager &storeMgr = ValMgr.getStateManager().getStoreManager();
     145                 : 
     146                 :     // Delegate to store manager to get the result of casting a region to a
     147                 :     // different type.  If the MemRegion* returned is NULL, this expression
     148                 :     // evaluates to UnknownVal.
     149             1621:     R = storeMgr.CastRegion(R, castTy);
                     1617: branch 0 taken
                        4: branch 1 taken
                        4: branch 4 taken
                     1617: branch 5 taken
                     1617: branch 7 taken
                        4: branch 8 taken
     150             1621:     return R ? SVal(loc::MemRegionVal(R)) : UnknownVal();
     151                 :   }
     152                 : 
     153             1105: DispatchCast:
     154                 :   // All other cases.
     155                 :   return isa<Loc>(val) ? EvalCastL(cast<Loc>(val), castTy)
                      192: branch 1 taken
                      913: branch 2 taken
                      913: branch 8 taken
                      192: branch 9 taken
                      192: branch 11 taken
                      913: branch 12 taken
     156             1105:                        : EvalCastNL(cast<NonLoc>(val), castTy);
     157                 : }

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