zcov: / lib/Checker/BasicValueFactory.cpp


Files: 1 Branches Taken: 55.7% 44 / 79
Generated: 2010-02-10 01:31 Branches Executed: 82.3% 65 / 79
Line Coverage: 75.2% 88 / 117


Programs: 1 Runs 2897


       1                 : //=== BasicValueFactory.cpp - Basic values for Path Sens analysis --*- 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 BasicValueFactory, a class that manages the lifetime
      11                 : //  of APSInt objects and symbolic constraints used by GRExprEngine
      12                 : //  and related classes.
      13                 : //
      14                 : //===----------------------------------------------------------------------===//
      15                 : 
      16                 : #include "clang/Checker/PathSensitive/BasicValueFactory.h"
      17                 : 
      18                 : using namespace clang;
      19                 : 
      20                 : void CompoundValData::Profile(llvm::FoldingSetNodeID& ID, QualType T,
      21              110:                               llvm::ImmutableList<SVal> L) {
      22              110:   T.Profile(ID);
      23              110:   ID.AddPointer(L.getInternalPointer());
      24              110: }
      25                 : 
      26                 : void LazyCompoundValData::Profile(llvm::FoldingSetNodeID& ID,
      27               52:                                   const void *store,const TypedRegion *region) {
      28               52:   ID.AddPointer(store);
      29               52:   ID.AddPointer(region);
      30               52: }
      31                 : 
      32                 : typedef std::pair<SVal, uintptr_t> SValData;
      33                 : typedef std::pair<SVal, SVal> SValPair;
      34                 : 
      35                 : namespace llvm {
      36                 : template<> struct FoldingSetTrait<SValData> {
      37               10:   static inline void Profile(const SValData& X, llvm::FoldingSetNodeID& ID) {
      38               10:     X.first.Profile(ID);
      39               10:     ID.AddPointer( (void*) X.second);
      40               10:   }
      41                 : };
      42                 : 
      43                 : template<> struct FoldingSetTrait<SValPair> {
      44                0:   static inline void Profile(const SValPair& X, llvm::FoldingSetNodeID& ID) {
      45                0:     X.first.Profile(ID);
      46                0:     X.second.Profile(ID);
      47                0:   }
      48                 : };
      49                 : }
      50                 : 
      51                 : typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValData> >
      52                 :   PersistentSValsTy;
      53                 : 
      54                 : typedef llvm::FoldingSet<llvm::FoldingSetNodeWrapper<SValPair> >
      55                 :   PersistentSValPairsTy;
      56                 : 
      57             2138: BasicValueFactory::~BasicValueFactory() {
      58                 :   // Note that the dstor for the contents of APSIntSet will never be called,
      59                 :   // so we iterate over the set and invoke the dstor for each APSInt.  This
      60                 :   // frees an aux. memory allocated to represent very large constants.
                     7171: branch 4 taken
                     2138: branch 5 taken
                        0: branch 10 not taken
                        0: branch 11 not taken
      61             9309:   for (APSIntSetTy::iterator I=APSIntSet.begin(), E=APSIntSet.end(); I!=E; ++I)
      62             7171:     I->getValue().~APSInt();
      63                 : 
                       72: branch 0 taken
                     2066: branch 1 taken
                       72: branch 3 taken
                       72: branch 4 taken
      64             2138:   delete (PersistentSValsTy*) PersistentSVals;
                        0: branch 0 not taken
                     2138: branch 1 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
      65             2138:   delete (PersistentSValPairsTy*) PersistentSValPairs;
      66             2138: }
      67                 : 
      68            25739: const llvm::APSInt& BasicValueFactory::getValue(const llvm::APSInt& X) {
      69            25739:   llvm::FoldingSetNodeID ID;
      70                 :   void* InsertPos;
      71                 :   typedef llvm::FoldingSetNodeWrapper<llvm::APSInt> FoldNodeTy;
      72                 : 
      73            25739:   X.Profile(ID);
      74            25739:   FoldNodeTy* P = APSIntSet.FindNodeOrInsertPos(ID, InsertPos);
      75                 : 
                     7171: branch 0 taken
                    18568: branch 1 taken
      76            25739:   if (!P) {
      77             7171:     P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
                     7171: branch 1 taken
                        0: branch 2 not taken
      78             7171:     new (P) FoldNodeTy(X);
                     7171: branch 0 taken
                        0: branch 1 not taken
      79             7171:     APSIntSet.InsertNode(P, InsertPos);
      80                 :   }
      81                 : 
      82            25739:   return *P;
      83                 : }
      84                 : 
      85                 : const llvm::APSInt& BasicValueFactory::getValue(const llvm::APInt& X,
      86             5175:                                                 bool isUnsigned) {
      87             5175:   llvm::APSInt V(X, isUnsigned);
      88             5175:   return getValue(V);
      89                 : }
      90                 : 
      91                 : const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, unsigned BitWidth,
      92             5867:                                            bool isUnsigned) {
      93             5867:   llvm::APSInt V(BitWidth, isUnsigned);
      94             5867:   V = X;
      95             5867:   return getValue(V);
      96                 : }
      97                 : 
      98             3064: const llvm::APSInt& BasicValueFactory::getValue(uint64_t X, QualType T) {
      99                 : 
     100             3064:   unsigned bits = Ctx.getTypeSize(T);
                     2456: branch 2 taken
                      608: branch 3 taken
                      176: branch 5 taken
                     2280: branch 6 taken
     101             3064:   llvm::APSInt V(bits, T->isUnsignedIntegerType() || Loc::IsLocType(T));
     102             3064:   V = X;
     103             3064:   return getValue(V);
     104                 : }
     105                 : 
     106                 : const CompoundValData*
     107                 : BasicValueFactory::getCompoundValData(QualType T,
     108              109:                                       llvm::ImmutableList<SVal> Vals) {
     109                 : 
     110              109:   llvm::FoldingSetNodeID ID;
     111              109:   CompoundValData::Profile(ID, T, Vals);
     112                 :   void* InsertPos;
     113                 : 
     114              109:   CompoundValData* D = CompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
     115                 : 
                      109: branch 0 taken
                        0: branch 1 not taken
     116              109:   if (!D) {
     117              109:     D = (CompoundValData*) BPAlloc.Allocate<CompoundValData>();
                      109: branch 1 taken
                        0: branch 2 not taken
     118              109:     new (D) CompoundValData(T, Vals);
     119              109:     CompoundValDataSet.InsertNode(D, InsertPos);
     120                 :   }
     121                 : 
     122              109:   return D;
     123                 : }
     124                 : 
     125                 : const LazyCompoundValData*
     126                 : BasicValueFactory::getLazyCompoundValData(const void *store,
     127               52:                                           const TypedRegion *region) {
     128               52:   llvm::FoldingSetNodeID ID;
     129               52:   LazyCompoundValData::Profile(ID, store, region);
     130                 :   void* InsertPos;
     131                 : 
     132                 :   LazyCompoundValData *D =
     133               52:     LazyCompoundValDataSet.FindNodeOrInsertPos(ID, InsertPos);
     134                 : 
                       52: branch 0 taken
                        0: branch 1 not taken
     135               52:   if (!D) {
     136               52:     D = (LazyCompoundValData*) BPAlloc.Allocate<LazyCompoundValData>();
                       52: branch 1 taken
                        0: branch 2 not taken
     137               52:     new (D) LazyCompoundValData(store, region);
     138               52:     LazyCompoundValDataSet.InsertNode(D, InsertPos);
     139                 :   }
     140                 : 
     141               52:   return D;
     142                 : }
     143                 : 
     144                 : const llvm::APSInt*
     145                 : BasicValueFactory::EvaluateAPSInt(BinaryOperator::Opcode Op,
     146             1359:                              const llvm::APSInt& V1, const llvm::APSInt& V2) {
     147                 : 
                        0: branch 0 not taken
                       12: branch 1 taken
                       27: branch 2 taken
                        0: branch 3 not taken
                      837: branch 4 taken
                       32: branch 5 taken
                      104: branch 6 taken
                        4: branch 7 taken
                      141: branch 8 taken
                       28: branch 9 taken
                        0: branch 10 not taken
                        0: branch 11 not taken
                      149: branch 12 taken
                        3: branch 13 taken
                        0: branch 14 not taken
                       22: branch 15 taken
                        0: branch 16 not taken
     148             1359:   switch (Op) {
     149                 :     default:
     150                0:       assert (false && "Invalid Opcode.");
     151                 : 
     152                 :     case BinaryOperator::Mul:
     153               12:       return &getValue( V1 * V2 );
     154                 : 
     155                 :     case BinaryOperator::Div:
     156               27:       return &getValue( V1 / V2 );
     157                 : 
     158                 :     case BinaryOperator::Rem:
     159                0:       return &getValue( V1 % V2 );
     160                 : 
     161                 :     case BinaryOperator::Add:
     162              837:       return &getValue( V1 + V2 );
     163                 : 
     164                 :     case BinaryOperator::Sub:
     165               32:       return &getValue( V1 - V2 );
     166                 : 
     167                 :     case BinaryOperator::Shl: {
     168                 : 
     169                 :       // FIXME: This logic should probably go higher up, where we can
     170                 :       // test these conditions symbolically.
     171                 : 
     172                 :       // FIXME: Expand these checks to include all undefined behavior.
     173                 : 
                      104: branch 1 taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                      104: branch 5 taken
                        0: branch 6 not taken
                      104: branch 7 taken
     174              104:       if (V2.isSigned() && V2.isNegative())
     175                0:         return NULL;
     176                 : 
     177              104:       uint64_t Amt = V2.getZExtValue();
     178                 : 
                        0: branch 1 not taken
                      104: branch 2 taken
     179              104:       if (Amt > V1.getBitWidth())
     180                0:         return NULL;
     181                 : 
     182              104:       return &getValue( V1.operator<<( (unsigned) Amt ));
     183                 :     }
     184                 : 
     185                 :     case BinaryOperator::Shr: {
     186                 : 
     187                 :       // FIXME: This logic should probably go higher up, where we can
     188                 :       // test these conditions symbolically.
     189                 : 
     190                 :       // FIXME: Expand these checks to include all undefined behavior.
     191                 : 
                        4: branch 1 taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                        4: branch 5 taken
                        0: branch 6 not taken
                        4: branch 7 taken
     192                4:       if (V2.isSigned() && V2.isNegative())
     193                0:         return NULL;
     194                 : 
     195                4:       uint64_t Amt = V2.getZExtValue();
     196                 : 
                        0: branch 1 not taken
                        4: branch 2 taken
     197                4:       if (Amt > V1.getBitWidth())
     198                0:         return NULL;
     199                 : 
     200                4:       return &getValue( V1.operator>>( (unsigned) Amt ));
     201                 :     }
     202                 : 
     203                 :     case BinaryOperator::LT:
     204              141:       return &getTruthValue( V1 < V2 );
     205                 : 
     206                 :     case BinaryOperator::GT:
     207               28:       return &getTruthValue( V1 > V2 );
     208                 : 
     209                 :     case BinaryOperator::LE:
     210                0:       return &getTruthValue( V1 <= V2 );
     211                 : 
     212                 :     case BinaryOperator::GE:
     213                0:       return &getTruthValue( V1 >= V2 );
     214                 : 
     215                 :     case BinaryOperator::EQ:
     216              149:       return &getTruthValue( V1 == V2 );
     217                 : 
     218                 :     case BinaryOperator::NE:
     219                3:       return &getTruthValue( V1 != V2 );
     220                 : 
     221                 :       // Note: LAnd, LOr, Comma are handled specially by higher-level logic.
     222                 : 
     223                 :     case BinaryOperator::And:
     224                0:       return &getValue( V1 & V2 );
     225                 : 
     226                 :     case BinaryOperator::Or:
     227               22:       return &getValue( V1 | V2 );
     228                 : 
     229                 :     case BinaryOperator::Xor:
     230                0:       return &getValue( V1 ^ V2 );
     231                 :   }
     232                 : }
     233                 : 
     234                 : 
     235                 : const std::pair<SVal, uintptr_t>&
     236               93: BasicValueFactory::getPersistentSValWithData(const SVal& V, uintptr_t Data) {
     237                 : 
     238                 :   // Lazily create the folding set.
                       72: branch 0 taken
                       21: branch 1 taken
     239               93:   if (!PersistentSVals) PersistentSVals = new PersistentSValsTy();
     240                 : 
     241               93:   llvm::FoldingSetNodeID ID;
     242                 :   void* InsertPos;
     243               93:   V.Profile(ID);
     244               93:   ID.AddPointer((void*) Data);
     245                 : 
     246               93:   PersistentSValsTy& Map = *((PersistentSValsTy*) PersistentSVals);
     247                 : 
     248                 :   typedef llvm::FoldingSetNodeWrapper<SValData> FoldNodeTy;
     249               93:   FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
     250                 : 
                       83: branch 0 taken
                       10: branch 1 taken
     251               93:   if (!P) {
     252               83:     P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
                       83: branch 2 taken
                        0: branch 3 not taken
     253               83:     new (P) FoldNodeTy(std::make_pair(V, Data));
                       83: branch 0 taken
                        0: branch 1 not taken
     254               83:     Map.InsertNode(P, InsertPos);
     255                 :   }
     256                 : 
     257               93:   return P->getValue();
     258                 : }
     259                 : 
     260                 : const std::pair<SVal, SVal>&
     261                0: BasicValueFactory::getPersistentSValPair(const SVal& V1, const SVal& V2) {
     262                 : 
     263                 :   // Lazily create the folding set.
                        0: branch 0 not taken
                        0: branch 1 not taken
     264                0:   if (!PersistentSValPairs) PersistentSValPairs = new PersistentSValPairsTy();
     265                 : 
     266                0:   llvm::FoldingSetNodeID ID;
     267                 :   void* InsertPos;
     268                0:   V1.Profile(ID);
     269                0:   V2.Profile(ID);
     270                 : 
     271                0:   PersistentSValPairsTy& Map = *((PersistentSValPairsTy*) PersistentSValPairs);
     272                 : 
     273                 :   typedef llvm::FoldingSetNodeWrapper<SValPair> FoldNodeTy;
     274                0:   FoldNodeTy* P = Map.FindNodeOrInsertPos(ID, InsertPos);
     275                 : 
                        0: branch 0 not taken
                        0: branch 1 not taken
     276                0:   if (!P) {
     277                0:     P = (FoldNodeTy*) BPAlloc.Allocate<FoldNodeTy>();
                        0: branch 2 not taken
                        0: branch 3 not taken
     278                0:     new (P) FoldNodeTy(std::make_pair(V1, V2));
                        0: branch 0 not taken
                        0: branch 1 not taken
     279                0:     Map.InsertNode(P, InsertPos);
     280                 :   }
     281                 : 
     282                0:   return P->getValue();
     283                 : }
     284                 : 
     285                0: const SVal* BasicValueFactory::getPersistentSVal(SVal X) {
     286                0:   return &getPersistentSValWithData(X, 0).first;
     287                0: }
     288                 : 
     289                 : 

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