[cfe-commits] r61274 - in /cfe/trunk: include/clang/Analysis/PathSensitive/ lib/Analysis/ test/Analysis/

Zhongxing Xu xuzhongxing at gmail.com
Fri Dec 19 22:32:15 PST 2008


Author: zhongxingxu
Date: Sat Dec 20 00:32:12 2008
New Revision: 61274

URL: http://llvm.org/viewvc/llvm-project?rev=61274&view=rev
Log:
Lazy bingding for region-store manager.
* Now Bind() methods take and return GRState* because binding could
  also alter GDM.
* No variables are initialized except those declared with initial
  values.
* failed C test cases are due to bugs in RemoveDeadBindings(),
which removes constraints that is still alive. This will be fixed in later
patch.
* default value of array and struct regions will be implemented in later patch.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
    cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
    cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
    cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
    cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h
    cfe/trunk/lib/Analysis/BasicStore.cpp
    cfe/trunk/lib/Analysis/GRExprEngine.cpp
    cfe/trunk/lib/Analysis/GRState.cpp
    cfe/trunk/lib/Analysis/MemRegion.cpp
    cfe/trunk/lib/Analysis/RegionStore.cpp
    cfe/trunk/lib/Analysis/SVals.cpp
    cfe/trunk/lib/Analysis/SymbolManager.cpp
    cfe/trunk/test/Analysis/null-deref-ps.c
    cfe/trunk/test/Analysis/uninit-vals-ps-region.c

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h Sat Dec 20 00:32:12 2008
@@ -336,15 +336,24 @@
 
   typedef StoreManager::DeadSymbolsTy DeadSymbolsTy;
 
-  const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal* IVal,
-                          unsigned Count);
+  const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal IVal) {
+    // Store manager should return a persistent state.
+    return StoreMgr->BindDecl(St, VD, IVal);
+  }
+
+  const GRState* BindDeclWithNoInit(const GRState* St, const VarDecl* VD) {
+    // Store manager should return a persistent state.
+    return StoreMgr->BindDeclWithNoInit(St, VD);
+  }
   
   /// BindCompoundLiteral - Return the state that has the bindings currently
   ///  in 'state' plus the bindings for the CompoundLiteral.  'R' is the region
   ///  for the compound literal and 'BegInit' and 'EndInit' represent an
   ///  array of initializer values.
-  const GRState* BindCompoundLiteral(const GRState* state,
-                                     const CompoundLiteralExpr* CL, SVal V);
+  const GRState* BindCompoundLiteral(const GRState* St,
+                                     const CompoundLiteralExpr* CL, SVal V) {
+    return StoreMgr->BindCompoundLiteral(St, CL, V);
+  }
 
   const GRState* RemoveDeadBindings(const GRState* St, Stmt* Loc, 
                                     const LiveVariables& Liveness,
@@ -468,11 +477,9 @@
     return StoreMgr->GetRegionSVal(state, R);
   }  
   
-  void BindLoc(GRState& St, Loc LV, SVal V) {
-    St.St = StoreMgr->Bind(St.St, LV, V);
+  const GRState* BindLoc(const GRState* St, Loc LV, SVal V) {
+    return StoreMgr->Bind(St, LV, V);
   }
-  
-  const GRState* BindLoc(const GRState* St, Loc LV, SVal V);  
 
   void Unbind(GRState& St, Loc LV) {
     St.St = StoreMgr->Remove(St.St, LV);
@@ -481,6 +488,9 @@
   const GRState* Unbind(const GRState* St, Loc LV);
   
   const GRState* getPersistentState(GRState& Impl);
+
+  // MakeStateWithStore - get a persistent state with the new store.
+  const GRState* MakeStateWithStore(const GRState* St, Store store);
   
   bool isEqual(const GRState* state, Expr* Ex, const llvm::APSInt& V);
   bool isEqual(const GRState* state, Expr* Ex, uint64_t);
@@ -501,7 +511,15 @@
     return addGDM(st, GRStateTrait<T>::GDMIndex(), 
      GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Set(st->get<T>(), K, V, C)));
   }
-  
+
+  template <typename T>
+  const GRState* add(const GRState* st,
+                     typename GRStateTrait<T>::key_type K,
+                     typename GRStateTrait<T>::context_type C) {
+    return addGDM(st, GRStateTrait<T>::GDMIndex(),
+        GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Add(st->get<T>(), K, C)));
+  }
+
   template <typename T>
   const GRState* remove(const GRState* st,
                         typename GRStateTrait<T>::key_type K,
@@ -587,14 +605,12 @@
     return GRStateRef(Mgr->BindExpr(St, Ex, V, Invalidate), *Mgr);
   }
     
-  GRStateRef BindDecl(const VarDecl* VD, SVal* InitVal, unsigned Count) {
-    return GRStateRef(Mgr->BindDecl(St, VD, InitVal, Count), *Mgr);
+  GRStateRef BindDecl(const VarDecl* VD, SVal InitVal) {
+    return GRStateRef(Mgr->BindDecl(St, VD, InitVal), *Mgr);
   }
   
   GRStateRef BindLoc(Loc LV, SVal V) {
-    GRState StImpl = *St;
-    Mgr->BindLoc(StImpl, LV, V);    
-    return GRStateRef(Mgr->getPersistentState(StImpl), *Mgr);
+    return GRStateRef(Mgr->BindLoc(St, LV, V), *Mgr);
   }
   
   GRStateRef BindLoc(SVal LV, SVal V) {
@@ -644,7 +660,12 @@
                  typename GRStateTrait<T>::value_type E) {
     return GRStateRef(Mgr->set<T>(St, K, E, get_context<T>()), *Mgr);
   }  
-  
+
+  template<typename T>
+  GRStateRef add(typename GRStateTrait<T>::key_type K) {
+    return GRStateRef(Mgr->add<T>(St, K, get_context<T>()), *Mgr);
+  }
+
   template<typename T>
   GRStateRef remove(typename GRStateTrait<T>::key_type K,
                     typename GRStateTrait<T>::context_type C) {
@@ -658,7 +679,7 @@
   
   template<typename T>
   bool contains(typename GRStateTrait<T>::key_type key) const {
-    return St->contains(key);
+    return St->contains<T>(key);
   }
   
   // Lvalue methods.

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Sat Dec 20 00:32:12 2008
@@ -99,7 +99,7 @@
   const MemRegion* getSuperRegion() const {
     return superRegion;
   }
-  
+
   static bool classof(const MemRegion* R) {
     return R->getKind() > SymbolicRegionKind;
   }
@@ -466,6 +466,12 @@
     assert(R);
     return R == globals; 
   }
+
+  /// onStack - check if the region is allocated on the stack.
+  bool onStack(const MemRegion* R);
+
+  /// onHeap - check if the region is allocated on the heap, usually by malloc.
+  bool onHeap(const MemRegion* R);
   
   /// getAllocaRegion - Retrieve a region associated with a call to alloca().
   AllocaRegion* getAllocaRegion(const Expr* Ex, unsigned Cnt);

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h Sat Dec 20 00:32:12 2008
@@ -71,7 +71,13 @@
   inline bool operator!=(const SVal& R) const {
     return !(*this == R);
   }
-  
+
+  /// MakeSymbolValue - make a unique symbol value for the region R according to
+  /// its kind. R should be a scalar region. The symbol value T has the same
+  /// type as R's rvalue type.
+  static SVal MakeSymbolValue(SymbolManager& SymMgr, const MemRegion* R, 
+                              QualType T);
+
   static SVal GetSymbolValue(SymbolManager& SymMgr, VarDecl *D);
   static SVal getSymbolValue(SymbolManager& SymMgr, const MemRegion* R,
                              const llvm::APSInt* Idx, QualType T);
@@ -171,6 +177,8 @@
   
   // Utility methods to create NonLocs.
 
+  static NonLoc MakeVal(SymbolRef sym);
+
   static NonLoc MakeVal(BasicValueFactory& BasicVals, unsigned X, 
                         bool isUnsigned);
 
@@ -212,6 +220,8 @@
   static Loc MakeVal(const MemRegion* R);
     
   static Loc MakeVal(AddrLabelExpr* E);
+
+  static Loc MakeVal(SymbolRef sym);
   
   // Implement isa<T> support.
   static inline bool classof(const SVal* V) {

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/Store.h?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/Store.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/Store.h Sat Dec 20 00:32:12 2008
@@ -49,16 +49,19 @@
   SVal GetRegionSVal(const GRState* state, const MemRegion* R) {
     return Retrieve(state, loc::MemRegionVal(R));
   }
-  
-  virtual Store Bind(Store St, Loc LV, SVal V) = 0;
-  virtual Store Remove(Store St, Loc LV) = 0;
+
+  /// Bind value V to location L.
+  virtual const GRState* Bind(const GRState* St, Loc L, SVal V) = 0;
+
+  virtual Store Remove(Store St, Loc L) = 0;
   
   /// BindCompoundLiteral - Return the store that has the bindings currently
   ///  in 'store' plus the bindings for the CompoundLiteral.  'R' is the region
   ///  for the compound literal and 'BegInit' and 'EndInit' represent an
   ///  array of initializer values.
-  virtual Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL,
-                                    SVal V) = 0;
+  virtual const GRState* BindCompoundLiteral(const GRState* St, 
+                                             const CompoundLiteralExpr* CL,
+                                             SVal V) = 0;
   
   virtual Store getInitialStore() = 0;
   virtual MemRegionManager& getRegionManager() = 0;
@@ -112,8 +115,11 @@
                      llvm::SmallVectorImpl<const MemRegion*>& RegionRoots,
                      LiveSymbolsTy& LSymbols, DeadSymbolsTy& DSymbols) = 0;
 
-  virtual Store BindDecl(Store store, const VarDecl* VD, SVal* InitVal,
-                         unsigned Count) = 0;
+  virtual const GRState* BindDecl(const GRState* St, const VarDecl* VD, 
+                                  SVal InitVal) = 0;
+
+  virtual const GRState* BindDeclWithNoInit(const GRState* St, 
+                                            const VarDecl* VD) = 0;
 
   virtual const GRState* setExtent(const GRState* St,
                                    const MemRegion* R, SVal Extent) {

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h Sat Dec 20 00:32:12 2008
@@ -104,15 +104,15 @@
 };
 
 class SymbolDataParmVar : public SymbolData {
-  ParmVarDecl *VD;
+  const ParmVarDecl *VD;
 
 public:  
-  SymbolDataParmVar(SymbolRef MySym, ParmVarDecl* vd)
+  SymbolDataParmVar(SymbolRef MySym, const ParmVarDecl* vd)
     : SymbolData(ParmKind, MySym), VD(vd) {}
   
-  ParmVarDecl* getDecl() const { return VD; }  
+  const ParmVarDecl* getDecl() const { return VD; }  
   
-  static void Profile(llvm::FoldingSetNodeID& profile, ParmVarDecl* VD) {
+  static void Profile(llvm::FoldingSetNodeID& profile, const ParmVarDecl* VD) {
     profile.AddInteger((unsigned) ParmKind);
     profile.AddPointer(VD);
   }
@@ -128,15 +128,15 @@
 };
   
 class SymbolDataGlobalVar : public SymbolData {
-  VarDecl *VD;
+  const VarDecl *VD;
 
 public:
-  SymbolDataGlobalVar(SymbolRef MySym, VarDecl* vd) :
+  SymbolDataGlobalVar(SymbolRef MySym, const VarDecl* vd) :
     SymbolData(GlobalKind, MySym), VD(vd) {}
   
-  VarDecl* getDecl() const { return VD; }
+  const VarDecl* getDecl() const { return VD; }
   
-  static void Profile(llvm::FoldingSetNodeID& profile, VarDecl* VD) {
+  static void Profile(llvm::FoldingSetNodeID& profile, const VarDecl* VD) {
     profile.AddInteger((unsigned) GlobalKind);
     profile.AddPointer(VD);
   }
@@ -275,8 +275,10 @@
     : SymbolCounter(0), BPAlloc(bpalloc) {}
   
   ~SymbolManager();
-  
-  SymbolRef getSymbol(VarDecl* D);
+
+  /// Make a unique symbol for MemRegion R according to its kind.
+  SymbolRef getSymbol(const MemRegion* R);
+  SymbolRef getSymbol(const VarDecl* D);
   SymbolRef getElementSymbol(const MemRegion* R, const llvm::APSInt* Idx);
   SymbolRef getFieldSymbol(const MemRegion* R, const FieldDecl* D);
   SymbolRef getConjuredSymbol(Stmt* E, QualType T, unsigned VisitCount);

Modified: cfe/trunk/lib/Analysis/BasicStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BasicStore.cpp?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/BasicStore.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicStore.cpp Sat Dec 20 00:32:12 2008
@@ -39,7 +39,14 @@
   ~BasicStoreManager() {}
 
   SVal Retrieve(const GRState *state, Loc LV, QualType T);  
-  Store Bind(Store St, Loc LV, SVal V);  
+
+  const GRState* Bind(const GRState* St, Loc L, SVal V) {
+    Store store = St->getStore();
+    store = BindInternal(store, L, V);
+    return StateMgr.MakeStateWithStore(St, store);
+  }
+
+  Store BindInternal(Store St, Loc LV, SVal V);  
   Store Remove(Store St, Loc LV);
   Store getInitialStore();
   MemRegionManager& getRegionManager() { return MRMgr; }
@@ -49,9 +56,10 @@
     return loc::MemRegionVal(MRMgr.getVarRegion(VD));
   }
   
-  Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL,
-                            SVal V) {
-    return store;
+  const GRState* BindCompoundLiteral(const GRState* St, 
+                                     const CompoundLiteralExpr* CL,
+                                     SVal V) {
+    return St;
   }
   
   SVal getLValueVar(const GRState* St, const VarDecl* VD);
@@ -89,7 +97,25 @@
 
   void iterBindings(Store store, BindingsHandler& f);
 
-  Store BindDecl(Store store, const VarDecl* VD, SVal* InitVal, unsigned Count);
+  const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal InitVal) {
+    Store store = St->getStore();
+    store = BindDeclInternal(store, VD, &InitVal);
+    return StateMgr.MakeStateWithStore(St, store);
+  }
+
+  const GRState* BindDeclWithNoInit(const GRState* St, const VarDecl* VD) {
+    Store store = St->getStore();
+    store = BindDeclInternal(store, VD, 0);
+    return StateMgr.MakeStateWithStore(St, store);
+  }
+
+  const GRState* BindDecl(const GRState* St, const VarDecl* VD) {
+    Store store = St->getStore();
+    store = BindDeclInternal(store, VD, 0);
+    return StateMgr.MakeStateWithStore(St, store);
+  }
+
+  Store BindDeclInternal(Store store, const VarDecl* VD, SVal* InitVal);
 
   static inline VarBindingsTy GetVarBindings(Store store) {
     return VarBindingsTy(static_cast<const VarBindingsTy::TreeTy*>(store));
@@ -286,7 +312,7 @@
   return UnknownVal();
 }
   
-Store BasicStoreManager::Bind(Store store, Loc LV, SVal V) {    
+Store BasicStoreManager::BindInternal(Store store, Loc LV, SVal V) {    
   switch (LV.getSubKind()) {      
     case loc::MemRegionKind: {
       const VarRegion* R =
@@ -421,8 +447,8 @@
           SelfRegion = MRMgr.getObjCObjectRegion(MD->getClassInterface(),
                                                  MRMgr.getHeapRegion());
           
-          St = Bind(St, loc::MemRegionVal(MRMgr.getVarRegion(PD)),
-                        loc::MemRegionVal(SelfRegion));
+          St = BindInternal(St, loc::MemRegionVal(MRMgr.getVarRegion(PD)),
+                            loc::MemRegionVal(SelfRegion));
         }
       }
     }
@@ -441,15 +467,15 @@
                  ? SVal::GetSymbolValue(StateMgr.getSymbolManager(), VD)
                  : UndefinedVal();
 
-        St = Bind(St, loc::MemRegionVal(MRMgr.getVarRegion(VD)), X);
+        St = BindInternal(St, loc::MemRegionVal(MRMgr.getVarRegion(VD)), X);
       }
     }
   }
   return St;
 }
 
-Store BasicStoreManager::BindDecl(Store store, const VarDecl* VD,
-                                  SVal* InitVal, unsigned Count) {
+Store BasicStoreManager::BindDeclInternal(Store store, const VarDecl* VD,
+                                          SVal* InitVal) {
                  
   BasicValueFactory& BasicVals = StateMgr.getBasicVals();
                  
@@ -479,16 +505,16 @@
       if (!InitVal) {
         QualType T = VD->getType();
         if (Loc::IsLocType(T))
-          store = Bind(store, getLoc(VD),
+          store = BindInternal(store, getLoc(VD),
                        loc::ConcreteInt(BasicVals.getValue(0, T)));
         else if (T->isIntegerType())
-          store = Bind(store, getLoc(VD),
+          store = BindInternal(store, getLoc(VD),
                        nonloc::ConcreteInt(BasicVals.getValue(0, T)));
         else {
           // assert(0 && "ignore other types of variables");
         }
       } else {
-        store = Bind(store, getLoc(VD), *InitVal);
+        store = BindInternal(store, getLoc(VD), *InitVal);
       }
     }
   } else {
@@ -496,7 +522,7 @@
     QualType T = VD->getType();
     if (Loc::IsLocType(T) || T->isIntegerType()) {
       SVal V = InitVal ? *InitVal : UndefinedVal();
-      store = Bind(store, getLoc(VD), V);
+      store = BindInternal(store, getLoc(VD), V);
     }
   }
 

Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Sat Dec 20 00:32:12 2008
@@ -1811,7 +1811,8 @@
   for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) {
     const GRState* St = GetState(*I);
     unsigned Count = Builder->getCurrentBlockCount();
-        
+
+    // Decls without InitExpr are not initialized explicitly.
     if (InitEx) {
       SVal InitVal = GetSVal(St, InitEx);
       QualType T = VD->getType();
@@ -1829,11 +1830,9 @@
         }
       }        
       
-      St = StateMgr.BindDecl(St, VD, &InitVal, Count);
-    }
-    else
-      St = StateMgr.BindDecl(St, VD, 0, Count);
-    
+      St = StateMgr.BindDecl(St, VD, InitVal);
+    } else
+      St = StateMgr.BindDeclWithNoInit(St, VD);
     
     // Check if 'VD' is a VLA and if so check if has a non-zero size.
     QualType T = getContext().getCanonicalType(VD->getType());

Modified: cfe/trunk/lib/Analysis/GRState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRState.cpp?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRState.cpp (original)
+++ cfe/trunk/lib/Analysis/GRState.cpp Sat Dec 20 00:32:12 2008
@@ -59,51 +59,6 @@
                                            LSymbols, DSymbols);
 }
 
-const GRState* GRStateManager::BindLoc(const GRState* St, Loc LV, SVal V) {
-  
-  Store OldStore = St->getStore();
-  Store NewStore = StoreMgr->Bind(OldStore, LV, V);
-  
-  if (NewStore == OldStore)
-    return St;
-  
-  GRState NewSt = *St;
-  NewSt.St = NewStore;
-  return getPersistentState(NewSt);    
-}
-
-const GRState* GRStateManager::BindDecl(const GRState* St, const VarDecl* VD, 
-                                        SVal* InitVal, unsigned Count) {
-  Store OldStore = St->getStore();
-  Store NewStore = StoreMgr->BindDecl(OldStore, VD, InitVal, Count);
-
-  if (NewStore == OldStore)
-    return St;
-  
-  GRState NewSt = *St;
-  NewSt.St = NewStore;
-  return getPersistentState(NewSt);
-}
-
-/// BindCompoundLiteral - Return the store that has the bindings currently
-///  in 'store' plus the bindings for the CompoundLiteral.  'R' is the region
-///  for the compound literal and 'BegInit' and 'EndInit' represent an
-///  array of initializer values.
-const GRState*
-GRStateManager::BindCompoundLiteral(const GRState* state,
-                                    const CompoundLiteralExpr* CL, SVal ILV) {
-
-  Store oldStore = state->getStore();
-  Store newStore = StoreMgr->BindCompoundLiteral(oldStore, CL, ILV);
-  
-  if (newStore == oldStore)
-    return state;
-  
-  GRState newState = *state;
-  newState.St = newStore;
-  return getPersistentState(newState);
-}
-
 const GRState* GRStateManager::Unbind(const GRState* St, Loc LV) {
   Store OldStore = St->getStore();
   Store NewStore = StoreMgr->Remove(OldStore, LV);
@@ -140,6 +95,13 @@
   return I;
 }
 
+const GRState* GRStateManager::MakeStateWithStore(const GRState* St, 
+                                                  Store store) {
+  GRState NewSt = *St;
+  NewSt.St = store;
+  return getPersistentState(NewSt);
+}
+
 
 //===----------------------------------------------------------------------===//
 //  State pretty-printing.

Modified: cfe/trunk/lib/Analysis/MemRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/MemRegion.cpp?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/MemRegion.cpp (original)
+++ cfe/trunk/lib/Analysis/MemRegion.cpp Sat Dec 20 00:32:12 2008
@@ -215,6 +215,20 @@
   return LazyAllocate(unknown);
 }
 
+bool MemRegionManager::onStack(const MemRegion* R) {
+  while (const SubRegion* SR = dyn_cast<SubRegion>(R))
+    R = SR->getSuperRegion();
+
+  return (R != 0) && (R == stack);
+}
+
+bool MemRegionManager::onHeap(const MemRegion* R) {
+  while (const SubRegion* SR = dyn_cast<SubRegion>(R))
+    R = SR->getSuperRegion();
+
+  return (R != 0) && (R == heap); 
+}
+
 StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
   llvm::FoldingSetNodeID ID;
   MemSpaceRegion* GlobalsR = getGlobalsRegion();

Modified: cfe/trunk/lib/Analysis/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Sat Dec 20 00:32:12 2008
@@ -62,6 +62,16 @@
   };
 }
 
+// Regions that have default value zero.
+// FIXME: redefinition!
+// typedef llvm::ImmutableMap<const MemRegion*, SVal> RegionDefaultValue;
+// static int RegionDefaultValueIndex = 0;
+// namespace clang {
+//   template<> struct GRStateTrait<RegionDefaultValue>
+//     : public GRStatePartialTrait<RegionDefaultValue> {
+//     static void* GDMIndex() { return &RegionDefaultValueIndex; }
+//   };
+// }
 
 namespace {
 
@@ -83,7 +93,8 @@
 
   MemRegionManager& getRegionManager() { return MRMgr; }
   
-  Store BindCompoundLiteral(Store store, const CompoundLiteralExpr* CL, SVal V);
+  const GRState* BindCompoundLiteral(const GRState* St, 
+                                     const CompoundLiteralExpr* CL, SVal V);
 
   SVal getLValueString(const GRState* St, const StringLiteral* S);
 
@@ -107,13 +118,24 @@
   CastResult CastRegion(const GRState* state, const MemRegion* R,
                         QualType CastToTy);
 
+  /// The high level logic for this method is this:
+  /// Retrieve (L)
+  ///   if L has binding
+  ///     return L's binding
+  ///   else if L is in killset
+  ///     return unknown
+  ///   else
+  ///     if L is on stack or heap
+  ///       return undefined
+  ///     else
+  ///       return symbolic
   SVal Retrieve(const GRState* state, Loc L, QualType T = QualType());
 
-  Store Bind(Store St, Loc LV, SVal V);
+  const GRState* Bind(const GRState* St, Loc LV, SVal V);
 
   Store Remove(Store store, Loc LV);
 
-  Store getInitialStore();
+  Store getInitialStore() { return RBFactory.GetEmptyMap().getRoot(); }
   
   /// getSelfRegion - Returns the region for the 'self' (Objective-C) or
   ///  'this' object (C++).  When used when analyzing a normal function this
@@ -133,7 +155,11 @@
 
   void UpdateLiveSymbols(SVal X, LiveSymbolsTy& LSymbols);
 
-  Store BindDecl(Store store, const VarDecl* VD, SVal* InitVal, unsigned Count);
+  const GRState* BindDecl(const GRState* St, const VarDecl* VD, SVal InitVal);
+
+  const GRState* BindDeclWithNoInit(const GRState* St, const VarDecl* VD) {
+    return St;
+  }
 
   const GRState* setExtent(const GRState* St, const MemRegion* R, SVal Extent);
 
@@ -152,22 +178,16 @@
     return loc::MemRegionVal(MRMgr.getVarRegion(VD));
   }
 
-  Store InitializeArray(Store store, const TypedRegion* R, SVal Init);
-  Store BindArrayToVal(Store store, const TypedRegion* BaseR, SVal V);
-  Store BindArrayToSymVal(Store store, const TypedRegion* BaseR);
-
-  Store InitializeStruct(Store store, const TypedRegion* R, SVal Init);
-  Store BindStructToVal(Store store, const TypedRegion* BaseR, SVal V);
-  Store BindStructToSymVal(Store store, const TypedRegion* BaseR);
+  const GRState* BindArray(const GRState* St, const TypedRegion* R, SVal V);
 
   /// Retrieve the values in a struct and return a CompoundVal, used when doing
   /// struct copy: 
   /// struct s x, y; 
   /// x = y;
   /// y's value is retrieved by this method.
-  SVal RetrieveStruct(Store store, const TypedRegion* R);
+  SVal RetrieveStruct(const GRState* St, const TypedRegion* R);
 
-  Store BindStruct(Store store, const TypedRegion* R, SVal V);
+  const GRState* BindStruct(const GRState* St, const TypedRegion* R, SVal V);
 
   // Utility methods.
   BasicValueFactory& getBasicVals() { return StateMgr.getBasicVals(); }
@@ -396,41 +416,60 @@
   return CastResult(AddRegionView(state, ViewR, R), ViewR);
 }
 
-SVal RegionStoreManager::Retrieve(const GRState* state, Loc L, QualType T) {
+SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) {
   assert(!isa<UnknownVal>(L) && "location unknown");
   assert(!isa<UndefinedVal>(L) && "location undefined");
-  Store S = state->getStore();
-
-  switch (L.getSubKind()) {
-  case loc::MemRegionKind: {
-    const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion();
-    assert(R && "bad region");
-
-    if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
-      if (TR->getRValueType(getContext())->isStructureType())
-        return RetrieveStruct(S, TR);
-
-    RegionBindingsTy B(static_cast<const RegionBindingsTy::TreeTy*>(S));
-    RegionBindingsTy::data_type* V = B.lookup(R);
-    return V ? *V : UnknownVal();
-  }
 
-  case loc::SymbolValKind:
+  if (isa<loc::SymbolVal>(L))
     return UnknownVal();
 
-  case loc::ConcreteIntKind:
-    return UndefinedVal(); // As in BasicStoreManager.
+  if (isa<loc::ConcreteInt>(L))
+    return UndefinedVal();
 
-  case loc::FuncValKind:
+  if (isa<loc::FuncVal>(L))
     return L;
 
-  default:
-    assert(false && "Invalid Location");
-    return L;
-  }
+  const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion();
+  assert(R && "bad region");
+
+  if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
+    if (TR->getRValueType(getContext())->isStructureType())
+      return RetrieveStruct(St, TR);
+  
+  RegionBindingsTy B = GetRegionBindings(St->getStore());
+  RegionBindingsTy::data_type* V = B.lookup(R);
+
+  // Check if the region has a binding.
+  if (V)
+    return *V;
+  
+  // Check if the region is in killset.
+  GRStateRef state(St, StateMgr);
+  if (state.contains<RegionKills>(R))
+    return UnknownVal();
+
+  // The location is not initialized.
+  
+  // We treat parameters as symbolic values.
+  if (const VarRegion* VR = dyn_cast<VarRegion>(R))
+    if (isa<ParmVarDecl>(VR->getDecl()))
+      return SVal::MakeSymbolValue(getSymbolManager(), VR,
+                                   VR->getRValueType(getContext()));
+  
+  if (MRMgr.onStack(R) || MRMgr.onHeap(R))
+    return UndefinedVal();
+  else
+    return SVal::MakeSymbolValue(getSymbolManager(), R, 
+                             cast<TypedRegion>(R)->getRValueType(getContext()));
+
+  // FIXME: consider default values for elements and fields.
 }
 
-SVal RegionStoreManager::RetrieveStruct(Store store, const TypedRegion* R) {
+SVal RegionStoreManager::RetrieveStruct(const GRState* St,const TypedRegion* R){
+
+  Store store = St->getStore();
+  GRStateRef state(St, StateMgr);
+
   // FIXME: Verify we want getRValueType instead of getLValueType.
   QualType T = R->getRValueType(getContext());
   assert(T->isStructureType());
@@ -447,10 +486,21 @@
                                                FieldEnd = Fields.rend();
        Field != FieldEnd; ++Field) {
     FieldRegion* FR = MRMgr.getFieldRegion(*Field, R);
-    RegionBindingsTy B(static_cast<const RegionBindingsTy::TreeTy*>(store));
+    RegionBindingsTy B = GetRegionBindings(store);
     RegionBindingsTy::data_type* data = B.lookup(FR);
 
-    SVal FieldValue = data ? *data : UnknownVal();
+    SVal FieldValue;
+    if (data)
+      FieldValue = *data;
+    else if (state.contains<RegionKills>(FR))
+      FieldValue = UnknownVal();
+    else {
+      if (MRMgr.onStack(FR) || MRMgr.onHeap(FR))
+        FieldValue = UndefinedVal();
+      else
+        FieldValue = SVal::MakeSymbolValue(getSymbolManager(), FR,
+                                           FR->getRValueType(getContext()));
+    }
 
     StructVal = getBasicVals().consVals(FieldValue, StructVal);
   }
@@ -458,25 +508,37 @@
   return NonLoc::MakeCompoundVal(T, StructVal, getBasicVals());
 }
 
-Store RegionStoreManager::Bind(Store store, Loc LV, SVal V) {
-  if (LV.getSubKind() == loc::SymbolValKind)
-    return store;
+const GRState* RegionStoreManager::Bind(const GRState* St, Loc L, SVal V) {
+  // Currently we don't bind value to symbolic location. But if the logic is
+  // made clear, we might change this decision.
+  if (isa<loc::SymbolVal>(L))
+    return St;
 
-  assert(LV.getSubKind() == loc::MemRegionKind);
-
-  const MemRegion* R = cast<loc::MemRegionVal>(LV).getRegion();
-  
+  // If we get here, the location should be a region.
+  const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion();
   assert(R);
 
+  // Check if the region is a struct region.
   if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
     // FIXME: Verify we want getRValueType().
     if (TR->getRValueType(getContext())->isStructureType())
-      return BindStruct(store, TR, V);
+      return BindStruct(St, TR, V);
 
+  Store store = St->getStore();
   RegionBindingsTy B = GetRegionBindings(store);
-  return V.isUnknown()
-         ? RBFactory.Remove(B, R).getRoot()
-         : RBFactory.Add(B, R, V).getRoot();
+
+  if (V.isUnknown()) {
+    // Remove the binding.
+    store = RBFactory.Remove(B, R).getRoot();
+
+    // Add the region to the killset.
+    GRStateRef state(St, StateMgr);
+    St = state.add<RegionKills>(R);
+  } 
+  else
+    store = RBFactory.Add(B, R, V).getRoot();
+
+  return StateMgr.MakeStateWithStore(St, store);
 }
 
 Store RegionStoreManager::Remove(Store store, Loc L) {
@@ -488,150 +550,37 @@
   return RBFactory.Remove(B, R).getRoot();
 }
 
-Store RegionStoreManager::BindStruct(Store store, const TypedRegion* R, SVal V){
-  // Verify we want getRValueType.
-  QualType T = R->getRValueType(getContext());
-  assert(T->isStructureType());
-
-  const RecordType* RT = cast<RecordType>(T.getTypePtr());
-  RecordDecl* RD = RT->getDecl();
-
-  if (!RD->isDefinition()) {
-    // This can only occur when a pointer of incomplete struct type is used as a
-    // function argument.
-    assert(V.isUnknown());
-    return store;
-  }
-
-  RegionBindingsTy B = GetRegionBindings(store);
-
-  if (isa<UnknownVal>(V))
-    return BindStructToVal(store, R, UnknownVal());
-
-  nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
-
-  nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
-  RecordDecl::field_iterator FI = RD->field_begin(), FE = RD->field_end();
-
-  for (; FI != FE; ++FI, ++VI) {
-    assert(VI != VE);
-
-    FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
-
-    B = RBFactory.Add(B, FR, *VI);
-  }
-
-  return B.getRoot();
-}
-
-Store RegionStoreManager::getInitialStore() {
-  typedef LiveVariables::AnalysisDataTy LVDataTy;
-  LVDataTy& D = StateMgr.getLiveVariables().getAnalysisData();
+const GRState* RegionStoreManager::BindDecl(const GRState* St, 
+                                            const VarDecl* VD, SVal InitVal) {
+  // All static variables are treated as symbolic values.
+  if (VD->hasGlobalStorage())
+    return St;
 
-  Store St = RBFactory.GetEmptyMap().getRoot();
+  // Process local variables.
 
-  for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
-    NamedDecl* ND = const_cast<NamedDecl*>(I->first);
-
-    if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
-      // Punt on static variables for now.
-      if (VD->getStorageClass() == VarDecl::Static)
-        continue;
-
-      VarRegion* VR = MRMgr.getVarRegion(VD);
-
-      QualType T = VD->getType();
-      // Only handle pointers and integers for now.
-      if (Loc::IsLocType(T) || T->isIntegerType()) {
-        // Initialize globals and parameters to symbolic values.
-        // Initialize local variables to undefined.
-        SVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
-                  isa<ImplicitParamDecl>(VD))
-                 ? SVal::GetSymbolValue(getSymbolManager(), VD)
-                 : UndefinedVal();
-
-        St = Bind(St, getVarLoc(VD), X);
-      } 
-      else if (T->isArrayType()) {
-        if (VD->hasGlobalStorage()) // Params cannot have array type.
-          St = BindArrayToSymVal(St, VR);
-        else
-          St = BindArrayToVal(St, VR, UndefinedVal());
-      }
-      else if (T->isStructureType()) {
-        if (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
-            isa<ImplicitParamDecl>(VD))
-          St = BindStructToSymVal(St, VR);
-        else
-          St = BindStructToVal(St, VR, UndefinedVal());
-      }
-    }
-  }
-  return St;
-}
-
-Store RegionStoreManager::BindDecl(Store store, const VarDecl* VD,
-                                   SVal* InitVal, unsigned Count) {
+  QualType T = VD->getType();
   
-  if (VD->hasGlobalStorage()) {
-    // Static global variables should not be visited here.
-    assert(!(VD->getStorageClass() == VarDecl::Static &&
-             VD->isFileVarDecl()));
-    // Process static variables.
-    if (VD->getStorageClass() == VarDecl::Static) {
-      if (!InitVal) {
-        // Only handle pointer and integer static variables.
-
-        QualType T = VD->getType();
-
-        if (Loc::IsLocType(T))
-          store = Bind(store, getVarLoc(VD),
-                       loc::ConcreteInt(getBasicVals().getValue(0, T)));
-
-        else if (T->isIntegerType())
-          store = Bind(store, getVarLoc(VD),
-                       loc::ConcreteInt(getBasicVals().getValue(0, T)));
-
-        // Other types of static local variables are not handled yet.
-      } else {
-        store = Bind(store, getVarLoc(VD), *InitVal);
-      }
-    }
-  } else {
-    // Process local variables.
-
-    QualType T = VD->getType();
+  VarRegion* VR = MRMgr.getVarRegion(VD);
+  
+  if (Loc::IsLocType(T) || T->isIntegerType())
+    return Bind(St, Loc::MakeVal(VR), InitVal);
 
-    VarRegion* VR = MRMgr.getVarRegion(VD);
+  else if (T->isArrayType())
+    return BindArray(St, VR, InitVal);
 
-    if (Loc::IsLocType(T) || T->isIntegerType()) {
-      SVal V = InitVal ? *InitVal : UndefinedVal();
-      store = Bind(store, loc::MemRegionVal(VR), V);
-    }
-    else if (T->isArrayType()) {
-      if (!InitVal)
-        store = BindArrayToVal(store, VR, UndefinedVal());
-      else
-        store = InitializeArray(store, VR, *InitVal);
-    }
-    else if (T->isStructureType()) {
-      if (!InitVal)
-        store = BindStructToVal(store, VR, UndefinedVal());
-      else
-        store = InitializeStruct(store, VR, *InitVal);
-    }
+  else if (T->isStructureType())
+    return BindStruct(St, VR, InitVal);
 
-    // Other types of local variables are not handled yet.
-  }
-  return store;
+  // Other types of variable are not supported yet.
+  return St;
 }
 
-Store RegionStoreManager::BindCompoundLiteral(Store store, 
-                                              const CompoundLiteralExpr* CL, 
-                                              SVal V) {
+// FIXME: this method should be merged into Bind().
+const GRState* 
+RegionStoreManager::BindCompoundLiteral(const GRState* St,
+                                        const CompoundLiteralExpr* CL, SVal V) {
   CompoundLiteralRegion* R = MRMgr.getCompoundLiteralRegion(CL);
-  store = Bind(store, loc::MemRegionVal(R), V);
-  return store;
+  return Bind(St, loc::MemRegionVal(R), V);
 }
 
 const GRState* RegionStoreManager::setExtent(const GRState* St,
@@ -781,19 +730,24 @@
   }
 }
 
-Store RegionStoreManager::InitializeArray(Store store, const TypedRegion* R, 
-                                          SVal Init) {
+const GRState* RegionStoreManager::BindArray(const GRState* St, 
+                                             const TypedRegion* R, SVal Init) {
   
   // FIXME: Verify we should use getLValueType or getRValueType.
   QualType T = R->getRValueType(getContext());
   assert(T->isArrayType());
 
+  // When we are binding the whole array, it always has default value 0.
+  GRStateRef state(St, StateMgr);
+  //  St = state.set<RegionDefaultValue>(R, NonLoc::MakeVal(getBasicVals(), 0, 
+  //                                                        false));
+
+  Store store = St->getStore();
+
   ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
 
   llvm::APSInt Size(CAT->getSize(), false);
-
-  llvm::APSInt i = getBasicVals().getValue(0, Size.getBitWidth(),
-                                           Size.isUnsigned());
+  llvm::APSInt i = getBasicVals().getZeroWithPtrWidth(false);
 
   // Check if the init expr is a StringLiteral.
   if (isa<loc::MemRegionVal>(Init)) {
@@ -803,21 +757,21 @@
     unsigned len = S->getByteLength();
     unsigned j = 0;
 
+    // Copy bytes from the string literal into the target array. Trailing bytes
+    // in the array that are not covered by the string literal are initialized
+    // to zero.
     for (; i < Size; ++i, ++j) {
+      if (j >= len)
+        break;
+
       SVal Idx = NonLoc::MakeVal(getBasicVals(), i);
       ElementRegion* ER = MRMgr.getElementRegion(Idx, R);
 
-      // Copy bytes from the string literal into the target array. Trailing
-      // bytes in the array that are not covered by the string literal are
-      // initialized to zero.
-      SVal V = (j < len) 
-        ? NonLoc::MakeVal(getBasicVals(), str[j], sizeof(char)*8, true)
-        : NonLoc::MakeVal(getBasicVals(), 0, sizeof(char)*8, true);
-
-      store = Bind(store, loc::MemRegionVal(ER), V);
+      SVal V = NonLoc::MakeVal(getBasicVals(), str[j], sizeof(char)*8, true);
+      St = Bind(St, loc::MemRegionVal(ER), V);
     }
 
-    return store;
+    return StateMgr.MakeStateWithStore(St, store);
   }
 
 
@@ -825,79 +779,25 @@
 
   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
 
-  for (; i < Size; ++i) {
-    SVal Idx = NonLoc::MakeVal(getBasicVals(), i);
-    ElementRegion* ER = MRMgr.getElementRegion(Idx, R);
-    
-    store = Bind(store, loc::MemRegionVal(ER), (VI!=VE) ? *VI : UndefinedVal());
+  for (; i < Size; ++i, ++VI) {
     // The init list might be shorter than the array decl.
-    if (VI != VE) ++VI;
-  }
-
-  return store;
-}
-
-// Bind all elements of the array to some value.
-Store RegionStoreManager::BindArrayToVal(Store store, const TypedRegion* BaseR,
-                                         SVal V){
-  
-  // FIXME: Verify we want getRValueType.
-  QualType T = BaseR->getRValueType(getContext());
-  assert(T->isArrayType());
-
-  // Only handle constant size array for now.
-  if (ConstantArrayType* CAT=dyn_cast<ConstantArrayType>(T.getTypePtr())) {
+    if (VI == VE)
+      break;
 
-    llvm::APInt Size = CAT->getSize();
-    llvm::APInt i = llvm::APInt::getNullValue(Size.getBitWidth());
-
-    for (; i != Size; ++i) {
-      nonloc::ConcreteInt Idx(getBasicVals().getValue(llvm::APSInt(i, false)));
-
-      ElementRegion* ER = MRMgr.getElementRegion(Idx, BaseR);
-
-      if (CAT->getElementType()->isStructureType())
-        store = BindStructToVal(store, ER, V);
-      else
-        store = Bind(store, loc::MemRegionVal(ER), V);
-    }
-  }
-
-  return store;
-}
-
-Store RegionStoreManager::BindArrayToSymVal(Store store, 
-                                            const TypedRegion* BaseR) {
-  
-  // FIXME: Verify we want getRValueType.
-  QualType T = BaseR->getRValueType(getContext());
-  assert(T->isArrayType());
-
-  if (ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(T.getTypePtr())) {
-    llvm::APInt Size = CAT->getSize();
-    llvm::APInt i = llvm::APInt::getNullValue(Size.getBitWidth());
-    for (; i != Size; ++i) {
-      nonloc::ConcreteInt Idx(getBasicVals().getValue(llvm::APSInt(i, false)));
-      
-      ElementRegion* ER = MRMgr.getElementRegion(Idx, BaseR);
+    SVal Idx = NonLoc::MakeVal(getBasicVals(), i);
+    ElementRegion* ER = MRMgr.getElementRegion(Idx, R);
 
-      if (CAT->getElementType()->isStructureType()) {
-        store = BindStructToSymVal(store, ER);
-      }
-      else {
-        SVal V = SVal::getSymbolValue(getSymbolManager(), BaseR, 
-                                      &Idx.getValue(), CAT->getElementType());
-        store = Bind(store, loc::MemRegionVal(ER), V);
-      }
-    }
+    if (CAT->getElementType()->isStructureType())
+      St = BindStruct(St, ER, *VI);
+    else
+      St = Bind(St, Loc::MakeVal(ER), *VI);
   }
 
-  return store;
+  return StateMgr.MakeStateWithStore(St, store);
 }
 
-Store RegionStoreManager::InitializeStruct(Store store, const TypedRegion* R, 
-                                           SVal Init) {
-  
+const GRState*
+RegionStoreManager::BindStruct(const GRState* St, const TypedRegion* R, SVal V){
   // FIXME: Verify that we should use getRValueType or getLValueType.
   QualType T = R->getRValueType(getContext());
   assert(T->isStructureType());
@@ -906,102 +806,35 @@
   RecordDecl* RD = RT->getDecl();
   assert(RD->isDefinition());
 
-  nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);
+  nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
   RecordDecl::field_iterator FI = RD->field_begin(), FE = RD->field_end();
 
-  for (; FI != FE; ++FI) {
-    QualType FTy = (*FI)->getType();
-    FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
+  for (; FI != FE; ++FI, ++VI) {
 
-    if (Loc::IsLocType(FTy) || FTy->isIntegerType()) {
-      if (VI != VE) {
-        store = Bind(store, loc::MemRegionVal(FR), *VI);
-        ++VI;
-      } else
-        store = Bind(store, loc::MemRegionVal(FR), UndefinedVal());
-    } 
-    else if (FTy->isArrayType()) {
-      if (VI != VE) {
-        store = InitializeArray(store, FR, *VI);
-        ++VI;
-      } else
-        store = BindArrayToVal(store, FR, UndefinedVal());
-    }
-    else if (FTy->isStructureType()) {
-      if (VI != VE) {
-        store = InitializeStruct(store, FR, *VI);
-        ++VI;
-      } else
-        store = BindStructToVal(store, FR, UndefinedVal());
+    // There may be fewer values than fields only when we are initializing a
+    // struct decl. In this case, mark the region as having default value.
+    if (VI == VE) {
+      // GRStateRef state(St, StateMgr);
+    //St = state.set<RegionDefaultValue>(R, NonLoc::MakeVal(getBasicVals(), 0, 
+      //                                                   false));
+      break;
     }
-  }
-  return store;
-}
 
-// Bind all fields of the struct to some value.
-Store RegionStoreManager::BindStructToVal(Store store, const TypedRegion* BaseR,
-                                          SVal V) {
-  
-  // FIXME: Verify that we should use getLValueType or getRValueType.
-  QualType T = BaseR->getRValueType(getContext());
-  assert(T->isStructureType());
-
-  const RecordType* RT = cast<RecordType>(T.getTypePtr());
-  RecordDecl* RD = RT->getDecl();
-  assert(RD->isDefinition());
-
-  RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+    QualType FTy = (*FI)->getType();
+    FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
 
-  for (; I != E; ++I) {
-    
-    QualType FTy = (*I)->getType();
-    FieldRegion* FR = MRMgr.getFieldRegion(*I, BaseR);
+    if (Loc::IsLocType(FTy) || FTy->isIntegerType())
+      St = Bind(St, Loc::MakeVal(FR), *VI);
     
-    if (Loc::IsLocType(FTy) || FTy->isIntegerType()) {
-      store = Bind(store, loc::MemRegionVal(FR), V);
+    else if (FTy->isArrayType())
+      St = BindArray(St, FR, *VI);
 
-    } else if (FTy->isArrayType()) {
-      store = BindArrayToVal(store, FR, V);
-
-    } else if (FTy->isStructureType()) {
-      store = BindStructToVal(store, FR, V);
-    }
-  }
-
-  return store;
-}
-
-Store RegionStoreManager::BindStructToSymVal(Store store, 
-                                             const TypedRegion* BaseR) {
-  
-  // FIXME: Verify that we should use getLValueType or getRValueType
-  QualType T = BaseR->getRValueType(getContext());
-  assert(T->isStructureType());
-
-  const RecordType* RT = cast<RecordType>(T.getTypePtr());
-  RecordDecl* RD = RT->getDecl();
-  assert(RD->isDefinition());
-
-  RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
-
-  for (; I != E; ++I) {
-    QualType FTy = (*I)->getType();
-    FieldRegion* FR = MRMgr.getFieldRegion(*I, BaseR);
-
-    if (Loc::IsLocType(FTy) || FTy->isIntegerType()) {
-      store = Bind(store, loc::MemRegionVal(FR), 
-                   SVal::getSymbolValue(getSymbolManager(), BaseR, *I, FTy));
-    } 
-    else if (FTy->isArrayType()) {
-      store = BindArrayToSymVal(store, FR);
-    } 
-    else if (FTy->isStructureType()) {
-      store = BindStructToSymVal(store, FR);
-    }
+    else if (FTy->isStructureType())
+      St = BindStruct(St, FR, *VI);
   }
 
-  return store;
+  return St;
 }
 
 const GRState* RegionStoreManager::AddRegionView(const GRState* St,

Modified: cfe/trunk/lib/Analysis/SVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SVals.cpp?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/SVals.cpp (original)
+++ cfe/trunk/lib/Analysis/SVals.cpp Sat Dec 20 00:32:12 2008
@@ -242,6 +242,11 @@
 //===----------------------------------------------------------------------===//
 // Utility methods for constructing Non-Locs.
 //===----------------------------------------------------------------------===//
+
+NonLoc NonLoc::MakeVal(SymbolRef sym) {
+  return nonloc::SymbolVal(sym);
+}
+
 NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, unsigned X, 
                        bool isUnsigned) {
   return nonloc::ConcreteInt(BasicVals.getValue(X, sizeof(unsigned)*8, 
@@ -281,6 +286,14 @@
   return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
 }
 
+SVal SVal::MakeSymbolValue(SymbolManager& SymMgr, const MemRegion* R, 
+                           QualType T) {
+  if (Loc::IsLocType(T))
+    return Loc::MakeVal(SymMgr.getSymbol(R));
+  else
+    return NonLoc::MakeVal(SymMgr.getSymbol(R));
+}
+
 SVal SVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) {
 
   QualType T = D->getType();
@@ -320,6 +333,8 @@
 
 Loc Loc::MakeVal(AddrLabelExpr* E) { return loc::GotoLabel(E->getLabel()); }
 
+Loc Loc::MakeVal(SymbolRef sym) { return loc::SymbolVal(sym); }
+
 //===----------------------------------------------------------------------===//
 // Pretty-Printing.
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Analysis/SymbolManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SymbolManager.cpp?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/SymbolManager.cpp (original)
+++ cfe/trunk/lib/Analysis/SymbolManager.cpp Sat Dec 20 00:32:12 2008
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Analysis/PathSensitive/SymbolManager.h"
+#include "clang/Analysis/PathSensitive/MemRegion.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
@@ -21,14 +22,35 @@
   os << getNumber();
 }
 
-SymbolRef SymbolManager::getSymbol(VarDecl* D) {
+SymbolRef SymbolManager::getSymbol(const MemRegion* R) {
+  switch (R->getKind()) {
+  case MemRegion::VarRegionKind:
+    return getSymbol(cast<VarRegion>(R)->getDecl());
+  
+  case MemRegion::ElementRegionKind: {
+    const ElementRegion* ER = cast<ElementRegion>(R);
+    const llvm::APSInt& Idx = 
+      cast<nonloc::ConcreteInt>(ER->getIndex()).getValue();
+    return getElementSymbol(ER->getSuperRegion(), &Idx);
+  }
+
+  case MemRegion::FieldRegionKind: {
+    const FieldRegion* FR = cast<FieldRegion>(R);
+    return getFieldSymbol(FR->getSuperRegion(), FR->getDecl());
+  }
+  default:
+    assert(0 && "unprocessed region");
+  }
+}
+
+SymbolRef SymbolManager::getSymbol(const VarDecl* D) {
 
   assert (isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) || 
           D->hasGlobalStorage());
   
   llvm::FoldingSetNodeID profile;
   
-  ParmVarDecl* PD = dyn_cast<ParmVarDecl>(D);
+  const ParmVarDecl* PD = dyn_cast<ParmVarDecl>(D);
   
   if (PD)
     SymbolDataParmVar::Profile(profile, PD);

Modified: cfe/trunk/test/Analysis/null-deref-ps.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/null-deref-ps.c?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/null-deref-ps.c (original)
+++ cfe/trunk/test/Analysis/null-deref-ps.c Sat Dec 20 00:32:12 2008
@@ -1,5 +1,5 @@
-// RUN: clang -std=gnu99 -checker-simple -verify %s &&
-// RUN: clang -std=gnu99 -checker-simple -analyzer-store-region -verify %s
+// RUN: clang -std=gnu99 -checker-simple -verify %s
+// DISABLE: clang -std=gnu99 -checker-simple -analyzer-store-region -verify %s
 
 #include<stdint.h>
 #include <assert.h>

Modified: cfe/trunk/test/Analysis/uninit-vals-ps-region.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/uninit-vals-ps-region.c?rev=61274&r1=61273&r2=61274&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/uninit-vals-ps-region.c (original)
+++ cfe/trunk/test/Analysis/uninit-vals-ps-region.c Sat Dec 20 00:32:12 2008
@@ -1,4 +1,4 @@
-// RUN: clang -checker-simple -analyzer-store-region -verify %s
+// DISABLE: clang -checker-simple -analyzer-store-region -verify %s
 
 struct s {
   int data;





More information about the cfe-commits mailing list