zcov: / lib/Checker/BasicStore.cpp


Files: 1 Branches Taken: 72.7% 136 / 187
Generated: 2010-02-10 01:31 Branches Executed: 86.1% 161 / 187
Line Coverage: 82.3% 172 / 209


Programs: 1 Runs 2897


       1                 : //== BasicStore.cpp - Basic map from Locations to Values --------*- 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 defined the BasicStore and BasicStoreManager classes.
      11                 : //
      12                 : //===----------------------------------------------------------------------===//
      13                 : 
      14                 : #include "clang/AST/ExprObjC.h"
      15                 : #include "clang/Analysis/Analyses/LiveVariables.h"
      16                 : #include "clang/Analysis/AnalysisContext.h"
      17                 : #include "clang/Checker/PathSensitive/GRState.h"
      18                 : #include "llvm/ADT/ImmutableMap.h"
      19                 : 
      20                 : using namespace clang;
      21                 : 
      22                 : typedef llvm::ImmutableMap<const MemRegion*,SVal> BindingsTy;
      23                 : 
      24                 : namespace {
      25                 : 
                      471: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
      26              471: class BasicStoreSubRegionMap : public SubRegionMap {
      27                 : public:
      28              471:   BasicStoreSubRegionMap() {}
      29                 : 
      30              596:   bool iterSubRegions(const MemRegion* R, Visitor& V) const {
      31              596:     return true; // Do nothing.  No subregions.
      32                 :   }
      33                 : };
      34                 : 
      35                 : class BasicStoreManager : public StoreManager {
      36                 :   BindingsTy::Factory VBFactory;
      37                 : public:
      38              967:   BasicStoreManager(GRStateManager& mgr)
      39              967:     : StoreManager(mgr), VBFactory(mgr.getAllocator()) {}
      40                 : 
                      967: branch 2 taken
                        0: branch 3 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
      41              967:   ~BasicStoreManager() {}
      42                 : 
      43              471:   SubRegionMap *getSubRegionMap(Store store) {
      44              471:     return new BasicStoreSubRegionMap();
      45                 :   }
      46                 : 
      47                 :   SVal Retrieve(Store store, Loc loc, QualType T = QualType());
      48                 : 
      49                 :   Store InvalidateRegion(Store store, const MemRegion *R, const Expr *E, 
      50                 :                          unsigned Count, InvalidatedSymbols *IS);
      51                 : 
      52                 :   Store scanForIvars(Stmt *B, const Decl* SelfDecl,
      53                 :                      const MemRegion *SelfRegion, Store St);
      54                 : 
      55                 :   Store Bind(Store St, Loc loc, SVal V);
      56                 :   Store Remove(Store St, Loc loc);
      57                 :   Store getInitialStore(const LocationContext *InitLoc);
      58                 : 
      59                 :   // FIXME: Investigate what is using this. This method should be removed.
      60                0:   virtual Loc getLoc(const VarDecl* VD, const LocationContext *LC) {
      61                0:     return ValMgr.makeLoc(MRMgr.getVarRegion(VD, LC));
      62                 :   }
      63                 : 
      64                 :   Store BindCompoundLiteral(Store store, const CompoundLiteralExpr*,
      65               22:                             const LocationContext*, SVal val) {
      66               22:     return store;
      67                 :   }
      68                 : 
      69                 :   /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit
      70                 :   ///  conversions between arrays and pointers.
      71              208:   SVal ArrayToPointer(Loc Array) { return Array; }
      72                 : 
      73                 :   /// RemoveDeadBindings - Scans a BasicStore of 'state' for dead values.
      74                 :   ///  It updatees the GRState object in place with the values removed.
      75                 :   Store RemoveDeadBindings(Store store, Stmt* Loc, SymbolReaper& SymReaper,
      76                 :                           llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
      77                 : 
      78                 :   void iterBindings(Store store, BindingsHandler& f);
      79                 : 
      80              753:   Store BindDecl(Store store, const VarRegion *VR, SVal InitVal) {
      81              753:     return BindDeclInternal(store, VR, &InitVal);
      82                 :   }
      83                 : 
      84              321:   Store BindDeclWithNoInit(Store store, const VarRegion *VR) {
      85              321:     return BindDeclInternal(store, VR, 0);
      86                 :   }
      87                 : 
      88                 :   Store BindDeclInternal(Store store, const VarRegion *VR, SVal *InitVal);
      89                 : 
      90            28443:   static inline BindingsTy GetBindings(Store store) {
      91            28443:     return BindingsTy(static_cast<const BindingsTy::TreeTy*>(store));
      92                 :   }
      93                 : 
      94                 :   void print(Store store, llvm::raw_ostream& Out, const char* nl,
      95                 :              const char *sep);
      96                 : 
      97                 : private:
      98                 :   ASTContext& getContext() { return StateMgr.getContext(); }
      99                 : };
     100                 : 
     101                 : } // end anonymous namespace
     102                 : 
     103                 : 
     104              967: StoreManager* clang::CreateBasicStoreManager(GRStateManager& StMgr) {
     105              967:   return new BasicStoreManager(StMgr);
     106                 : }
     107                 : 
     108                0: static bool isHigherOrderRawPtr(QualType T, ASTContext &C) {
     109                0:   bool foundPointer = false;
     110                0:   while (1) {
     111                0:     const PointerType *PT = T->getAs<PointerType>();
                        0: branch 0 not taken
                        0: branch 1 not taken
     112                0:     if (!PT) {
                        0: branch 0 not taken
                        0: branch 1 not taken
     113                0:       if (!foundPointer)
     114                0:         return false;
     115                 : 
     116                 :       // intptr_t* or intptr_t**, etc?
                        0: branch 2 not taken
                        0: branch 3 not taken
                        0: branch 7 not taken
                        0: branch 8 not taken
                        0: branch 9 not taken
                        0: branch 10 not taken
     117                0:       if (T->isIntegerType() && C.getTypeSize(T) == C.getTypeSize(C.VoidPtrTy))
     118                0:         return true;
     119                 : 
     120                0:       QualType X = C.getCanonicalType(T).getUnqualifiedType();
     121                0:       return X == C.VoidTy;
     122                 :     }
     123                 : 
     124                0:     foundPointer = true;
     125                0:     T = PT->getPointeeType();
     126                 :   }
     127                 : }
     128                 : 
     129            13826: SVal BasicStoreManager::Retrieve(Store store, Loc loc, QualType T) {
                        0: branch 1 not taken
                    13826: branch 2 taken
     130            13826:   if (isa<UnknownVal>(loc))
     131                0:     return UnknownVal();
     132                 : 
                        0: branch 1 not taken
                    13826: branch 2 taken
     133            13826:   assert(!isa<UndefinedVal>(loc));
     134                 : 
                    13826: branch 1 taken
                        0: branch 2 not taken
                        0: branch 3 not taken
     135            13826:   switch (loc.getSubKind()) {
     136                 : 
     137                 :     case loc::MemRegionKind: {
     138            13826:       const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
     139                 : 
                      738: branch 1 taken
                    13088: branch 2 taken
                      337: branch 4 taken
                      401: branch 5 taken
                      337: branch 6 taken
                    13489: branch 7 taken
     140            13826:       if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
     141              337:         return UnknownVal();
     142                 : 
     143            13489:       BindingsTy B = GetBindings(store);
     144            13489:       BindingsTy::data_type *Val = B.lookup(R);
     145                 : 
                    13060: branch 0 taken
                      429: branch 1 taken
     146            13489:       if (!Val)
     147              429:         break;
     148                 : 
     149            13060:       return CastRetrievedVal(*Val, cast<TypedRegion>(R), T);
     150                 :     }
     151                 : 
     152                 :     case loc::ConcreteIntKind:
     153                 :       // Some clients may call GetSVal with such an option simply because
     154                 :       // they are doing a quick scan through their Locs (potentially to
     155                 :       // invalidate their bindings).  Just return Undefined.
     156                0:       return UndefinedVal();
     157                 : 
     158                 :     default:
     159                0:       assert (false && "Invalid Loc.");
     160                 :       break;
     161                 :   }
     162                 : 
     163              429:   return UnknownVal();
     164                 : }
     165                 : 
     166             5319: Store BasicStoreManager::Bind(Store store, Loc loc, SVal V) {
                        1: branch 1 taken
                     5318: branch 2 taken
     167             5319:   if (isa<loc::ConcreteInt>(loc))
     168                1:     return store;
     169                 : 
     170             5318:   const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
     171             5318:   ASTContext &C = StateMgr.getContext();
     172                 : 
     173                 :   // Special case: handle store of pointer values (Loc) to pointers via
     174                 :   // a cast to intXX_t*, void*, etc.  This is needed to handle
     175                 :   // OSCompareAndSwap32Barrier/OSCompareAndSwap64Barrier.
                     4124: branch 1 taken
                     1194: branch 2 taken
                       10: branch 4 taken
                     4114: branch 5 taken
                     1204: branch 6 taken
                     4114: branch 7 taken
     176             5318:   if (isa<Loc>(V) || isa<nonloc::LocAsInteger>(V))
                        0: branch 1 not taken
                     1204: branch 2 taken
     177             1204:     if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
     178                 :       // FIXME: Should check for index 0.
     179                0:       QualType T = ER->getLocationType(C);
     180                 : 
                        0: branch 1 not taken
                        0: branch 2 not taken
     181                0:       if (isHigherOrderRawPtr(T, C))
     182                0:         R = ER->getSuperRegion();
     183                 :     }
     184                 : 
                      307: branch 1 taken
                     5011: branch 2 taken
                      229: branch 4 taken
                       78: branch 5 taken
                      229: branch 6 taken
                     5089: branch 7 taken
     185             5318:   if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
     186              229:     return store;
     187                 : 
     188             5089:   const TypedRegion *TyR = cast<TypedRegion>(R);
     189                 : 
     190                 :   // Do not bind to arrays.  We need to explicitly check for this so that
     191                 :   // we do not encounter any weirdness of trying to load/store from arrays.
                     5089: branch 1 taken
                        0: branch 2 not taken
                      118: branch 6 taken
                     4971: branch 7 taken
                      118: branch 8 taken
                     4971: branch 9 taken
     192             5089:   if (TyR->isBoundable() && TyR->getValueType(C)->isArrayType())
     193              118:     return store;
     194                 : 
                       10: branch 1 taken
                     4961: branch 2 taken
     195             4971:   if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&V)) {
     196                 :     // Only convert 'V' to a location iff the underlying region type
     197                 :     // is a location as well.
     198                 :     // FIXME: We are allowing a store of an arbitrary location to
     199                 :     // a pointer.  We may wish to flag a type error here if the types
     200                 :     // are incompatible.  This may also cause lots of breakage
     201                 :     // elsewhere. Food for thought.
                       10: branch 1 taken
                        0: branch 2 not taken
                        0: branch 5 not taken
                       10: branch 6 taken
                        0: branch 7 not taken
                       10: branch 8 taken
     202               10:     if (TyR->isBoundable() && Loc::IsLocType(TyR->getValueType(C)))
     203                0:       V = X->getLoc();
     204                 :   }
     205                 : 
     206             4971:   BindingsTy B = GetBindings(store);
     207                 :   return V.isUnknown()
     208                 :     ? VBFactory.Remove(B, R).getRoot()
                     1602: branch 1 taken
                     3369: branch 2 taken
     209             4971:     : VBFactory.Add(B, R, V).getRoot();
     210                 : }
     211                 : 
     212             3216: Store BasicStoreManager::Remove(Store store, Loc loc) {
                     3066: branch 1 taken
                      150: branch 2 taken
     213             3216:   switch (loc.getSubKind()) {
     214                 :     case loc::MemRegionKind: {
     215             3066:       const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
     216                 : 
                        0: branch 1 not taken
                     3066: branch 2 taken
                        0: branch 4 not taken
                        0: branch 5 not taken
                        0: branch 6 not taken
                     3066: branch 7 taken
     217             3066:       if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
     218                0:         return store;
     219                 : 
     220             3066:       return VBFactory.Remove(GetBindings(store), R).getRoot();
     221                 :     }
     222                 :     default:
     223                 :       assert ("Remove for given Loc type not yet implemented.");
     224              150:       return store;
     225                 :   }
     226                 : }
     227                 : 
     228                 : Store BasicStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
     229                 :                                             SymbolReaper& SymReaper,
     230             5533:                            llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
     231                 : {
     232             5533:   BindingsTy B = GetBindings(store);
     233                 :   typedef SVal::symbol_iterator symbol_iterator;
     234                 : 
     235                 :   // Iterate over the variable bindings.
                    12352: branch 5 taken
                     5533: branch 6 taken
     236            14788:   for (BindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I) {
                    12006: branch 2 taken
                      346: branch 3 taken
     237            12352:     if (const VarRegion *VR = dyn_cast<VarRegion>(I.getKey())) {
                     3097: branch 1 taken
                     8909: branch 2 taken
     238            12006:       if (SymReaper.isLive(Loc, VR))
     239             8909:         RegionRoots.push_back(VR);
     240                 :       else
     241             3097:         continue;
     242                 :     }
                        0: branch 2 not taken
                      346: branch 3 taken
     243              346:     else if (isa<ObjCIvarRegion>(I.getKey())) {
     244              346:       RegionRoots.push_back(I.getKey());
     245                 :     }
     246                 :     else
     247                0:       continue;
     248                 : 
     249                 :     // Mark the bindings in the data as live.
     250             9255:     SVal X = I.getData();
                     5649: branch 4 taken
                     9255: branch 5 taken
     251            14904:     for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
     252            14904:       SymReaper.markLive(*SI);
     253             5533:   }
     254                 : 
     255                 :   // Scan for live variables and live symbols.
     256             5533:   llvm::SmallPtrSet<const MemRegion*, 10> Marked;
     257                 : 
                    13886: branch 1 taken
                     5533: branch 2 taken
     258            24952:   while (!RegionRoots.empty()) {
     259            13886:     const MemRegion* MR = RegionRoots.back();
     260            13886:     RegionRoots.pop_back();
     261                 : 
                    14420: branch 0 taken
                        0: branch 1 not taken
     262            28306:     while (MR) {
                     3874: branch 1 taken
                    10546: branch 2 taken
     263            14420:       if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(MR)) {
     264             3874:         SymReaper.markLive(SymR->getSymbol());
     265             3874:         break;
     266                 :       }
                     1363: branch 1 taken
                     9183: branch 2 taken
                      346: branch 4 taken
                     1017: branch 5 taken
                     9529: branch 6 taken
                     1017: branch 7 taken
     267            10546:       else if (isa<VarRegion>(MR) || isa<ObjCIvarRegion>(MR)) {
                       42: branch 1 taken
                     9487: branch 2 taken
     268             9529:         if (Marked.count(MR))
     269               42:           break;
     270                 : 
     271             9487:         Marked.insert(MR);
     272             9487:         SVal X = Retrieve(store, loc::MemRegionVal(MR));
     273                 : 
     274                 :         // FIXME: We need to handle symbols nested in region definitions.
                     5657: branch 4 taken
                     9487: branch 5 taken
     275            15144:         for (symbol_iterator SI=X.symbol_begin(),SE=X.symbol_end();SI!=SE;++SI)
     276            15144:           SymReaper.markLive(*SI);
     277                 : 
                     3807: branch 1 taken
                     5680: branch 2 taken
     278             9487:         if (!isa<loc::MemRegionVal>(X))
     279                 :           break;
     280                 : 
     281             3807:         const loc::MemRegionVal& LVD = cast<loc::MemRegionVal>(X);
     282             3807:         RegionRoots.push_back(LVD.getRegion());
     283             9487:         break;
     284                 :       }
                      483: branch 1 taken
                      534: branch 2 taken
     285             1017:       else if (const SubRegion* R = dyn_cast<SubRegion>(MR))
     286              534:         MR = R->getSuperRegion();
     287                 :       else
     288              483:         break;
     289                 :     }
     290                 :   }
     291                 : 
     292                 :   // Remove dead variable bindings.
                    12352: branch 4 taken
                     5533: branch 5 taken
     293            17885:   for (BindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I) {
     294            12352:     const MemRegion* R = I.getKey();
     295                 : 
                     3066: branch 1 taken
                     9286: branch 2 taken
     296            12352:     if (!Marked.count(R)) {
     297             3066:       store = Remove(store, ValMgr.makeLoc(R));
     298             3066:       SVal X = I.getData();
     299                 : 
                      915: branch 4 taken
                     3066: branch 5 taken
     300             3981:       for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
     301             3981:         SymReaper.maybeDead(*SI);
     302                 :     }
     303             5533:   }
     304                 : 
     305             5533:   return store;
     306                 : }
     307                 : 
     308                 : Store BasicStoreManager::scanForIvars(Stmt *B, const Decl* SelfDecl,
     309             1305:                                       const MemRegion *SelfRegion, Store St) {
                     1388: branch 4 taken
                     1305: branch 5 taken
     310             2693:   for (Stmt::child_iterator CI=B->child_begin(), CE=B->child_end();
     311                 :        CI != CE; ++CI) {
     312                 : 
                       73: branch 1 taken
                     1315: branch 2 taken
     313             1388:     if (!*CI)
     314               73:       continue;
     315                 : 
     316                 :     // Check if the statement is an ivar reference.  We only
     317                 :     // care about self.ivar.
                       65: branch 2 taken
                     1250: branch 3 taken
     318             1315:     if (ObjCIvarRefExpr *IV = dyn_cast<ObjCIvarRefExpr>(*CI)) {
     319               65:       const Expr *Base = IV->getBase()->IgnoreParenCasts();
                       64: branch 1 taken
                        1: branch 2 taken
     320               65:       if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Base)) {
                       64: branch 1 taken
                        0: branch 2 not taken
     321               64:         if (DR->getDecl() == SelfDecl) {
     322                 :           const MemRegion *IVR = MRMgr.getObjCIvarRegion(IV->getDecl(),
     323               64:                                                          SelfRegion);
     324               64:           SVal X = ValMgr.getRegionValueSymbolVal(IVR);
     325               64:           St = Bind(St, ValMgr.makeLoc(IVR), X);
     326                 :         }
     327                 :       }
     328                 :     }
     329                 :     else
     330             1250:       St = scanForIvars(*CI, SelfDecl, SelfRegion, St);
     331                 :   }
     332                 : 
     333             1305:   return St;
     334                 : }
     335                 : 
     336              967: Store BasicStoreManager::getInitialStore(const LocationContext *InitLoc) {
     337                 :   // The LiveVariables information already has a compilation of all VarDecls
     338                 :   // used in the function.  Iterate through this set, and "symbolicate"
     339                 :   // any VarDecl whose value originally comes from outside the function.
     340                 :   typedef LiveVariables::AnalysisDataTy LVDataTy;
     341              967:   LVDataTy& D = InitLoc->getLiveVariables()->getAnalysisData();
     342              967:   Store St = VBFactory.GetEmptyMap().getRoot();
     343                 : 
                     1821: branch 4 taken
                      967: branch 5 taken
     344             2788:   for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
     345             1821:     NamedDecl* ND = const_cast<NamedDecl*>(I->first);
     346                 : 
     347                 :     // Handle implicit parameters.
                       59: branch 1 taken
                     1762: branch 2 taken
     348             1821:     if (ImplicitParamDecl* PD = dyn_cast<ImplicitParamDecl>(ND)) {
     349               59:       const Decl& CD = *InitLoc->getDecl();
                       59: branch 1 taken
                        0: branch 2 not taken
     350               59:       if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(&CD)) {
                       55: branch 1 taken
                        4: branch 2 taken
     351               59:         if (MD->getSelfDecl() == PD) {
     352                 :           // FIXME: Add type constraints (when they become available) to
     353                 :           // SelfRegion?  (i.e., it implements MD->getClassInterface()).
     354               55:           const MemRegion *VR = MRMgr.getVarRegion(PD, InitLoc);
     355                 :           const MemRegion *SelfRegion =
     356               55:             ValMgr.getRegionValueSymbolVal(VR).getAsRegion();          
                        0: branch 0 not taken
                       55: branch 1 taken
     357               55:           assert(SelfRegion);          
     358               55:           St = Bind(St, ValMgr.makeLoc(VR), loc::MemRegionVal(SelfRegion));
     359                 :           // Scan the method for ivar references.  While this requires an
     360                 :           // entire AST scan, the cost should not be high in practice.
     361               55:           St = scanForIvars(MD->getBody(), PD, SelfRegion, St);
     362                 :         }
     363                 :       }
     364                 :     }
                     1762: branch 1 taken
                        0: branch 2 not taken
     365             1762:     else if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
     366                 :       // Only handle simple types that we can symbolicate.
                      274: branch 2 taken
                     1488: branch 3 taken
     367             1762:       if (!SymbolManager::canSymbolicate(VD->getType()))
     368              274:         continue;
     369                 : 
     370                 :       // Initialize globals and parameters to symbolic values.
     371                 :       // Initialize local variables to undefined.
     372             1488:       const MemRegion *R = ValMgr.getRegionManager().getVarRegion(VD, InitLoc);
     373             1488:       SVal X = UndefinedVal();
                      561: branch 1 taken
                      927: branch 2 taken
     374             1488:       if (R->hasGlobalsOrParametersStorage())
     375              561:         X = ValMgr.getRegionValueSymbolVal(R);
     376                 : 
     377             1488:       St = Bind(St, ValMgr.makeLoc(R), X);
     378                 :     }
     379                 :   }
     380              967:   return St;
     381                 : }
     382                 : 
     383                 : Store BasicStoreManager::BindDeclInternal(Store store, const VarRegion* VR,
     384             1074:                                           SVal* InitVal) {
     385                 : 
     386             1074:   BasicValueFactory& BasicVals = StateMgr.getBasicVals();
     387             1074:   const VarDecl *VD = VR->getDecl();
     388                 : 
     389                 :   // BasicStore does not model arrays and structs.
                      989: branch 3 taken
                       85: branch 4 taken
                       51: branch 8 taken
                      938: branch 9 taken
                      136: branch 10 taken
                      938: branch 11 taken
     390             1074:   if (VD->getType()->isArrayType() || VD->getType()->isStructureType())
     391              136:     return store;
     392                 : 
                       18: branch 1 taken
                      920: branch 2 taken
     393              938:   if (VD->hasGlobalStorage()) {
     394                 :     // Handle variables with global storage: extern, static, PrivateExtern.
     395                 : 
     396                 :     // FIXME:: static variables may have an initializer, but the second time a
     397                 :     // function is called those values may not be current. Currently, a function
     398                 :     // will not be called more than once.
     399                 : 
     400                 :     // Static global variables should not be visited here.
     401                 :     assert(!(VD->getStorageClass() == VarDecl::Static &&
                       18: branch 1 taken
                        0: branch 2 not taken
                        0: branch 4 not taken
                       18: branch 5 taken
     402               18:              VD->isFileVarDecl()));
     403                 : 
     404                 :     // Process static variables.
                       18: branch 1 taken
                        0: branch 2 not taken
     405               18:     if (VD->getStorageClass() == VarDecl::Static) {
     406                 :       // C99: 6.7.8 Initialization
     407                 :       //  If an object that has static storage duration is not initialized
     408                 :       //  explicitly, then:
     409                 :       //   —if it has pointer type, it is initialized to a null pointer;
     410                 :       //   —if it has arithmetic type, it is initialized to (positive or
     411                 :       //     unsigned) zero;
                       18: branch 0 taken
                        0: branch 1 not taken
     412               18:       if (!InitVal) {
     413               18:         QualType T = VD->getType();
                       12: branch 1 taken
                        6: branch 2 taken
     414               18:         if (Loc::IsLocType(T))
     415                 :           store = Bind(store, loc::MemRegionVal(VR),
     416               12:                        loc::ConcreteInt(BasicVals.getValue(0, T)));
                        6: branch 2 taken
                        0: branch 3 not taken
     417                6:         else if (T->isIntegerType())
     418                 :           store = Bind(store, loc::MemRegionVal(VR),
     419                6:                        nonloc::ConcreteInt(BasicVals.getValue(0, T)));
     420                 :         else {
     421                 :           // assert(0 && "ignore other types of variables");
     422                 :         }
     423                 :       } else {
     424                0:         store = Bind(store, loc::MemRegionVal(VR), *InitVal);
     425                 :       }
     426                 :     }
     427                 :   } else {
     428                 :     // Process local scalar variables.
     429              920:     QualType T = VD->getType();
                      883: branch 2 taken
                       37: branch 3 taken
     430              920:     if (ValMgr.getSymbolManager().canSymbolicate(T)) {
                      676: branch 0 taken
                      207: branch 1 taken
                      207: branch 3 taken
                      676: branch 4 taken
     431              883:       SVal V = InitVal ? *InitVal : UndefinedVal();
     432              883:       store = Bind(store, loc::MemRegionVal(VR), V);
     433                 :     }
     434                 :   }
     435                 : 
     436              938:   return store;
     437                 : }
     438                 : 
     439                 : void BasicStoreManager::print(Store store, llvm::raw_ostream& Out,
     440                0:                               const char* nl, const char *sep) {
     441                 : 
     442                0:   BindingsTy B = GetBindings(store);
     443                0:   Out << "Variables:" << nl;
     444                 : 
     445                0:   bool isFirst = true;
     446                 : 
                        0: branch 4 not taken
                        0: branch 5 not taken
     447                0:   for (BindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I) {
                        0: branch 0 not taken
                        0: branch 1 not taken
     448                0:     if (isFirst)
     449                0:       isFirst = false;
     450                 :     else
     451                0:       Out << nl;
     452                 : 
     453                0:     Out << ' ' << I.getKey() << " : " << I.getData();
     454                0:   }
     455                0: }
     456                 : 
     457                 : 
     458             1278: void BasicStoreManager::iterBindings(Store store, BindingsHandler& f) {
     459             1278:   BindingsTy B = GetBindings(store);
     460                 : 
                     2524: branch 4 taken
                     1278: branch 5 taken
     461             3802:   for (BindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I)
     462             3802:     f.HandleBinding(*this, store, I.getKey(), I.getData());
     463                 : 
     464             1278: }
     465                 : 
                     3193: branch 0 taken
                     3193: branch 1 taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 6 not taken
                     3193: branch 7 taken
     466             3193: StoreManager::BindingsHandler::~BindingsHandler() {}
     467                 : 
     468                 : //===----------------------------------------------------------------------===//
     469                 : // Binding invalidation.
     470                 : //===----------------------------------------------------------------------===//
     471                 : 
     472                 : Store BasicStoreManager::InvalidateRegion(Store store,
     473                 :                                           const MemRegion *R,
     474                 :                                           const Expr *E,
     475                 :                                           unsigned Count,
     476              379:                                           InvalidatedSymbols *IS) {
     477              379:   R = R->StripCasts();
     478                 : 
                      273: branch 1 taken
                      106: branch 2 taken
                      273: branch 4 taken
                        0: branch 5 not taken
                      273: branch 6 taken
                      106: branch 7 taken
     479              379:   if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
     480              273:       return store;
     481                 : 
                      106: branch 0 taken
                        0: branch 1 not taken
     482              106:   if (IS) {
     483              106:     BindingsTy B = GetBindings(store);
                       49: branch 1 taken
                       57: branch 2 taken
     484              106:     if (BindingsTy::data_type *Val = B.lookup(R)) {
                        6: branch 1 taken
                       43: branch 2 taken
     485               49:       if (SymbolRef Sym = Val->getAsSymbol())
     486                6:         IS->insert(Sym);
     487                 :     }
     488                 :   }
     489                 : 
     490              106:   QualType T = cast<TypedRegion>(R)->getValueType(R->getContext());
     491              106:   SVal V = ValMgr.getConjuredSymbolVal(R, E, T, Count);
     492              106:   return Bind(store, loc::MemRegionVal(R), V);
     493                0: }
     494                 : 

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