[cfe-commits] r54788 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRState.h lib/Analysis/CFRefCount.cpp lib/Analysis/GRState.cpp

Ted Kremenek kremenek at apple.com
Thu Aug 14 14:16:54 PDT 2008


Author: kremenek
Date: Thu Aug 14 16:16:54 2008
New Revision: 54788

URL: http://llvm.org/viewvc/llvm-project?rev=54788&view=rev
Log:
Migrated retain/release checker to use the Generic Data Map in GRState (instead
of using CheckerState).

Removed CheckerState from GRState.

Added class GRStateRef which wraps GRState* and GRStateManager*. This is handy
for generating new states with a single handle.

Added member template set/get functions to GRStateRef/GRState/GRStateManager for
accessing the Generic Data Map.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h
    cfe/trunk/lib/Analysis/CFRefCount.cpp
    cfe/trunk/lib/Analysis/GRState.cpp

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=54788&r1=54787&r2=54788&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h Thu Aug 14 16:16:54 2008
@@ -47,6 +47,8 @@
 // GRState- An ImmutableMap type Stmt*/Decl*/Symbols to RVals.
 //===----------------------------------------------------------------------===//
 
+template<typename T> struct GRStateTrait;
+  
 /// GRState - This class encapsulates the actual data values for
 ///  for a "state" in our symbolic value tracking.  It is intended to be
 ///  used as a functional object; that is once it is created and made
@@ -74,7 +76,6 @@
   GenericDataMap   GDM;
   ConstNotEqTy     ConstNotEq;
   ConstEqTy        ConstEq;
-  void*            CheckerState;
   
 public:
   
@@ -85,8 +86,7 @@
       St(st),
       GDM(gdm),
       ConstNotEq(CNE),
-      ConstEq(CE),
-      CheckerState(NULL) {}
+      ConstEq(CE) {}
   
   /// Copy ctor - We must explicitly define this or else the "Next" ptr
   ///  in FoldingSetNode will also get copied.
@@ -96,8 +96,7 @@
       St(RHS.St),
       GDM(RHS.GDM),
       ConstNotEq(RHS.ConstNotEq),
-      ConstEq(RHS.ConstEq),
-      CheckerState(RHS.CheckerState) {} 
+      ConstEq(RHS.ConstEq) {}
   
   /// getEnvironment - Return the environment associated with this state.
   ///  The environment is the mapping from expressions to values.
@@ -118,7 +117,6 @@
     V->GDM.Profile(ID);
     V->ConstNotEq.Profile(ID);
     V->ConstEq.Profile(ID);
-    ID.AddPointer(V->CheckerState);
   }
 
   /// Profile - Used to profile the contents of this object for inclusion
@@ -171,6 +169,22 @@
   ce_iterator ce_begin() const { return ConstEq.begin(); }
   ce_iterator ce_end() const { return ConstEq.end(); }
   
+  // Trait based GDM dispatch.  
+  void* const* FindGDM(void* K) const;
+  
+  template <typename T>
+  typename GRStateTrait<T>::data_type get() const {
+    return GRStateTrait<T>::MakeData(FindGDM(GRStateTrait<T>::GDMIndex()));
+  }
+  
+  template<typename T>
+  typename GRStateTrait<T>::lookup_type
+  get(typename GRStateTrait<T>::key_type key) const {
+    void* const* d = FindGDM(GRStateTrait<T>::GDMIndex());
+    return GRStateTrait<T>::Lookup(GRStateTrait<T>::MakeData(d), key);
+  }
+  
+  // State pretty-printing.
   class Printer {
   public:
     virtual ~Printer() {}
@@ -183,7 +197,7 @@
   
   void printStdErr(Printer **Beg = 0, Printer **End = 0) const;  
   void printDOT(std::ostream& Out, Printer **Beg = 0, Printer **End = 0) const;
-};  
+};
   
 template<> struct GRTrait<GRState*> {
   static inline void* toPtr(GRState* St)  { return (void*) St; }
@@ -195,6 +209,7 @@
   }
 };
   
+  
 class GRStateSet {
   typedef llvm::SmallPtrSet<const GRState*,5> ImplTy;
   ImplTy Impl;  
@@ -226,7 +241,11 @@
         S.Add(St);
     }
   };
-};
+};  
+  
+//===----------------------------------------------------------------------===//
+// GRStateManager - Factory object for GRStates.
+//===----------------------------------------------------------------------===//
   
 class GRStateManager {
   friend class GRExprEngine;
@@ -349,18 +368,8 @@
   }
   
   // Methods that manipulate the GDM.
-  const GRState* addGDM(const GRState* St, void* Key, void* Data) {
-    GRState::GenericDataMap M1 = St->getGDM();
-    GRState::GenericDataMap M2 = GDMFactory.Add(M2, Key, Data);    
-    
-    if (M1 == M2)
-      return St;
-    
-    GRState NewSt = *St;
-    NewSt.GDM = M2;
-    return getPersistentState(NewSt);
-  }
-
+  const GRState* addGDM(const GRState* St, void* Key, void* Data);
+  
   // Methods that query & manipulate the Store.
   RVal GetRVal(const GRState* St, LVal LV, QualType T = QualType()) {
     return StMgr->GetRVal(St->getStore(), LV, T);
@@ -389,6 +398,32 @@
   bool isEqual(const GRState* state, Expr* Ex, const llvm::APSInt& V);
   bool isEqual(const GRState* state, Expr* Ex, uint64_t);
   
+  // Trait based GDM dispatch.  
+  template <typename T>
+  const GRState* set(const GRState* st, typename GRStateTrait<T>::data_type D) {
+    return addGDM(st, GRStateTrait<T>::GDMIndex(),
+                  GRStateTrait<T>::MakeVoidPtr(D));
+  }
+  
+  template<typename T>
+  const GRState* set(const GRState* st,
+                     typename GRStateTrait<T>::key_type K,
+                     typename GRStateTrait<T>::value_type V,
+                     typename GRStateTrait<T>::context_type C) {
+    
+    return addGDM(st, GRStateTrait<T>::GDMIndex(), 
+     GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Set(st->get<T>(), K, V, C)));
+  }
+  
+  template <typename T>
+  const GRState* remove(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>::Remove(st->get<T>(), K, C)));
+  }
+  
   // Assumption logic.
   const GRState* Assume(const GRState* St, RVal Cond, bool Assumption,
                            bool& isFeasible) {
@@ -440,6 +475,86 @@
                                 const llvm::APSInt& V, bool& isFeasible);
 };
   
+//===----------------------------------------------------------------------===//
+// GRStateRef - A "fat" reference to GRState that also bundles GRStateManager.
+//===----------------------------------------------------------------------===//
+  
+class GRStateRef {
+  const GRState* St;
+  GRStateManager* Mgr;
+public:
+  GRStateRef(const GRState* st, GRStateManager& mgr) : St(st), Mgr(&mgr) {}
+
+  const GRState* getState() const { return St; } 
+  operator const GRState*() const { return St; }
+  GRStateManager& getManager() const { return *Mgr; }
+    
+  RVal GetRVal(Expr* Ex) {
+    return Mgr->GetRVal(St, Ex);
+  }
+  
+  RVal GetBlkExprRVal(Expr* Ex) {  
+    return Mgr->GetBlkExprRVal(St, Ex);
+  }
+  
+  RVal GetRVal(LVal LV, QualType T = QualType()) {
+    return Mgr->GetRVal(St, LV, T);
+  }
+  
+  GRStateRef SetRVal(Expr* Ex, RVal V, bool isBlkExpr, bool Invalidate) {
+    return GRStateRef(Mgr->SetRVal(St, Ex, V, isBlkExpr, Invalidate), *Mgr);
+  }
+  
+  GRStateRef SetRVal(Expr* Ex, RVal V) {
+    return GRStateRef(Mgr->SetRVal(St, Ex, V), *Mgr);
+  }
+  
+  GRStateRef SetRVal(LVal LV, RVal V) {
+    GRState StImpl = *St;
+    Mgr->SetRVal(StImpl, LV, V);    
+    return GRStateRef(Mgr->getPersistentState(StImpl), *Mgr);
+  }
+  
+  GRStateRef Unbind(LVal LV) {
+    return GRStateRef(Mgr->Unbind(St, LV), *Mgr);
+  }
+  
+  GRStateRef AddNE(SymbolID sym, const llvm::APSInt& V) {
+    return GRStateRef(Mgr->AddNE(St, sym, V), *Mgr);
+  }
+  
+  // Trait based GDM dispatch.
+  template<typename T>
+  typename GRStateTrait<T>::data_type get() const {
+    return St->get<T>();
+  }
+  
+  template<typename T>
+  typename GRStateTrait<T>::lookup_type
+  get(typename GRStateTrait<T>::key_type key) const {
+    return St->get<T>(key);
+  }
+  
+  template<typename T>
+  GRStateRef set(typename GRStateTrait<T>::data_type D) {
+    return GRStateRef(Mgr->set<T>(St, D), *Mgr);
+  }
+  
+  template<typename T>
+  GRStateRef set(typename GRStateTrait<T>::key_type K,
+                 typename GRStateTrait<T>::value_type E,
+                 typename GRStateTrait<T>::context_type C) {
+    return GRStateRef(Mgr->set<T>(St, K, E, C), *Mgr);
+  }
+  
+  template<typename T>
+  GRStateRef remove(typename GRStateTrait<T>::key_type K,
+                    typename GRStateTrait<T>::context_type C) {
+    return GRStateRef(Mgr->remove<T>(St, K, C), *Mgr);
+  }
+};
+  
+  
 } // end clang namespace
 
 #endif

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

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Thu Aug 14 16:16:54 2008
@@ -1192,20 +1192,60 @@
   }
 }
   
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// RefBindings - State used to track object reference counts.
+//===----------------------------------------------------------------------===//
+  
+typedef llvm::ImmutableMap<SymbolID, RefVal> RefBindings;
+typedef RefBindings::Factory RefBFactoryTy;
+  
+static int RefBIndex = 0;
+
+namespace clang {
+template<> struct GRStateTrait<RefBindings> {
+  typedef RefBindings             data_type;
+  typedef RefBFactoryTy&          context_type;  
+  typedef SymbolID                key_type;
+  typedef RefVal                  value_type;
+  typedef const RefVal*           lookup_type;
+  
+  static RefBindings MakeData(void* const* p) {
+    return p ? RefBindings((RefBindings::TreeTy*) *p) : RefBindings(0);
+  }  
+  static void* MakeVoidPtr(RefBindings B) {
+    return B.getRoot();
+  }  
+  static void* GDMIndex() {
+    return &RefBIndex;
+  }  
+  static lookup_type Lookup(RefBindings B, SymbolID K) {
+    return B.lookup(K);
+  }  
+  static data_type Set(RefBindings B, key_type K, value_type E,
+                       RefBFactoryTy& F) {
+    return F.Add(B, K, E);
+  }
+  
+  static data_type Remove(RefBindings B, SymbolID K, RefBFactoryTy& F) {
+    return F.Remove(B, K);
+  }
+};
+}  
+  
 //===----------------------------------------------------------------------===//
 // Transfer functions.
 //===----------------------------------------------------------------------===//
 
+namespace {
+  
 class VISIBILITY_HIDDEN CFRefCount : public GRSimpleVals {
 public:
   // Type definitions.  
-  typedef llvm::ImmutableMap<SymbolID, RefVal> RefBindings;
-  
-  typedef RefBindings::Factory RefBFactoryTy;
-  
   typedef llvm::DenseMap<GRExprEngine::NodeTy*,std::pair<Expr*, SymbolID> >
           ReleasesNotOwnedTy;
-  
+
   typedef ReleasesNotOwnedTy UseAfterReleasesTy;
     
   typedef llvm::DenseMap<GRExprEngine::NodeTy*, std::vector<SymbolID>*>
@@ -1225,30 +1265,18 @@
   ReleasesNotOwnedTy   ReleasesNotOwned;
   LeaksTy              Leaks;
   BindingsPrinter      Printer;  
-
-public:
-  
-  static RefBindings GetRefBindings(const GRState& StImpl) {
-    return RefBindings((const RefBindings::TreeTy*) StImpl.CheckerState);
-  }
-  
-  static RefBindings GetRefBindings(const GRState* state) {
-    return RefBindings((const RefBindings::TreeTy*) state->CheckerState);
-  }
-
-private:
-  
-  static void SetRefBindings(GRState& StImpl, RefBindings B) {
-    StImpl.CheckerState = B.getRoot();
-  }
-
-  RefBindings Remove(RefBindings B, SymbolID sym) {
-    return RefBFactory.Remove(B, sym);
-  }
   
   RefBindings Update(RefBindings B, SymbolID sym, RefVal V, ArgEffect E,
                      RefVal::Kind& hasErr);
   
+  RefVal::Kind& Update(GRStateRef& state, SymbolID sym, RefVal V,
+                       ArgEffect E, RefVal::Kind& hasErr) {
+    
+    state = state.set<RefBindings>(Update(state.get<RefBindings>(), sym, V, 
+                                          E, hasErr));
+    return hasErr;
+  }
+  
   void ProcessNonLeakError(ExplodedNodeSet<GRState>& Dst,
                            GRStmtNodeBuilder<GRState>& Builder,
                            Expr* NodeExpr, Expr* ErrorExpr,                        
@@ -1260,9 +1288,6 @@
                                       const GRState* St,
                                       SymbolID sid, RefVal V, bool& hasLeak);
   
-  const GRState* NukeBinding(GRStateManager& VMgr, const GRState* St,
-                                SymbolID sid);
-  
 public:
   
   CFRefCount(ASTContext& Ctx, bool gcenabled, const LangOptions& lopts)
@@ -1370,7 +1395,7 @@
 void CFRefCount::BindingsPrinter::Print(std::ostream& Out, const GRState* state,
                                         const char* nl, const char* sep) {
     
-  RefBindings B = GetRefBindings(state);
+  RefBindings B = state->get<RefBindings>();
   
   if (!B.isEmpty())
     Out << sep << nl;
@@ -1464,34 +1489,25 @@
                              ExplodedNode<GRState>* Pred) {
   
   // Get the state.
-  GRStateManager& StateMgr = Eng.getStateManager();  
-  const GRState* St = Builder.GetState(Pred);
+  GRStateRef state(Builder.GetState(Pred), Eng.getStateManager());
 
   // Evaluate the effect of the arguments.
-  GRState StVals = *St;
   RefVal::Kind hasErr = (RefVal::Kind) 0;
   unsigned idx = 0;
   Expr* ErrorExpr = NULL;
   SymbolID ErrorSym = 0;                                        
   
-  for (ExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {
-    
-    RVal V = StateMgr.GetRVal(St, *I);
+  for (ExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {    
+    RVal V = state.GetRVal(*I);
     
     if (isa<lval::SymbolVal>(V)) {
       SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
-      RefBindings B = GetRefBindings(StVals);      
-      
-      if (RefBindings::data_type* T = B.lookup(Sym)) {
-        B = Update(B, Sym, *T, GetArgE(Summ, idx), hasErr);
-        SetRefBindings(StVals, B);
-        
-        if (hasErr) {
+      if (RefBindings::data_type* T = state.get<RefBindings>(Sym))
+        if (Update(state, Sym, *T, GetArgE(Summ, idx), hasErr)) {
           ErrorExpr = *I;
           ErrorSym = Sym;
           break;
         }
-      }
     }  
     else if (isa<LVal>(V)) {
 #if 0
@@ -1515,58 +1531,48 @@
         //  disambiguate conjured symbols. 
 
         // Is the invalidated variable something that we were tracking?
-        RVal X = StateMgr.GetRVal(&StVals, *DV);
+        RVal X = state.GetRVal(*DV);
         
         if (isa<lval::SymbolVal>(X)) {
           SymbolID Sym = cast<lval::SymbolVal>(X).getSymbol();
-          SetRefBindings(StVals,RefBFactory.Remove(GetRefBindings(StVals),Sym));
+          state = state.remove<RefBindings>(Sym, RefBFactory);
         }
 
         // Set the value of the variable to be a conjured symbol.
         unsigned Count = Builder.getCurrentBlockCount();
         SymbolID NewSym = Eng.getSymbolManager().getConjuredSymbol(*I, Count);
-      
-        StateMgr.SetRVal(StVals, *DV,
-                         LVal::IsLValType(DV->getDecl()->getType())
-                         ? cast<RVal>(lval::SymbolVal(NewSym))
-                         : cast<RVal>(nonlval::SymbolVal(NewSym)));
+
+        state = state.SetRVal(*DV,
+                              LVal::IsLValType(DV->getDecl()->getType())
+                              ? cast<RVal>(lval::SymbolVal(NewSym))
+                              : cast<RVal>(nonlval::SymbolVal(NewSym)));
       }
       else {
         // Nuke all other arguments passed by reference.
-        StateMgr.Unbind(StVals, cast<LVal>(V));
+        state = state.Unbind(cast<LVal>(V));
       }
 #endif
     }
     else if (isa<nonlval::LValAsInteger>(V))
-      StateMgr.Unbind(StVals, cast<nonlval::LValAsInteger>(V).getLVal());
+      state = state.Unbind(cast<nonlval::LValAsInteger>(V).getLVal());
   } 
   
   // Evaluate the effect on the message receiver.  
   if (!ErrorExpr && Receiver) {
-    RVal V = StateMgr.GetRVal(St, Receiver);
-
+    RVal V = state.GetRVal(Receiver);
     if (isa<lval::SymbolVal>(V)) {
       SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
-      RefBindings B = GetRefBindings(StVals);      
-      
-      if (const RefVal* T = B.lookup(Sym)) {
-        B = Update(B, Sym, *T, GetReceiverE(Summ), hasErr);
-        SetRefBindings(StVals, B);
-        
-        if (hasErr) {
+      if (const RefVal* T = state.get<RefBindings>(Sym))
+        if (Update(state, Sym, *T, GetReceiverE(Summ), hasErr)) {
           ErrorExpr = Receiver;
           ErrorSym = Sym;
         }
-      }
     }
   }
-
-  // Get the persistent state.  
-  St = StateMgr.getPersistentState(StVals);
   
   // Process any errors.  
   if (hasErr) {
-    ProcessNonLeakError(Dst, Builder, Ex, ErrorExpr, Pred, St,
+    ProcessNonLeakError(Dst, Builder, Ex, ErrorExpr, Pred, state,
                         hasErr, ErrorSym);
     return;
   }
@@ -1592,7 +1598,7 @@
                ? cast<RVal>(lval::SymbolVal(Sym)) 
                : cast<RVal>(nonlval::SymbolVal(Sym));
         
-        St = StateMgr.SetRVal(St, Ex, X, Eng.getCFG().isBlkExpr(Ex), false);
+        state = state.SetRVal(Ex, X, Eng.getCFG().isBlkExpr(Ex), false);
       }      
       
       break;
@@ -1601,15 +1607,15 @@
       unsigned idx = RE.getIndex();
       assert (arg_end >= arg_beg);
       assert (idx < (unsigned) (arg_end - arg_beg));
-      RVal V = StateMgr.GetRVal(St, *(arg_beg+idx));
-      St = StateMgr.SetRVal(St, Ex, V, Eng.getCFG().isBlkExpr(Ex), false);
+      RVal V = state.GetRVal(*(arg_beg+idx));
+      state = state.SetRVal(Ex, V, Eng.getCFG().isBlkExpr(Ex), false);
       break;
     }
       
     case RetEffect::ReceiverAlias: {
       assert (Receiver);
-      RVal V = StateMgr.GetRVal(St, Receiver);
-      St = StateMgr.SetRVal(St, Ex, V, Eng.getCFG().isBlkExpr(Ex), false);
+      RVal V = state.GetRVal(Receiver);
+      state = state.SetRVal(Ex, V, Eng.getCFG().isBlkExpr(Ex), false);
       break;
     }
       
@@ -1619,17 +1625,19 @@
       SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
       QualType RetT = GetReturnType(Ex, Eng.getContext());
       
-      GRState StImpl = *St;
+      state = state.set<RefBindings>(Sym, RefVal::makeOwned(RetT), RefBFactory);
+      state = state.SetRVal(Ex, lval::SymbolVal(Sym),
+                            Eng.getCFG().isBlkExpr(Ex), false);
+
+#if 0
       RefBindings B = GetRefBindings(StImpl);
       SetRefBindings(StImpl, RefBFactory.Add(B, Sym, RefVal::makeOwned(RetT)));
-      
-      St = StateMgr.SetRVal(StateMgr.getPersistentState(StImpl),
-                            Ex, lval::SymbolVal(Sym),
-                            Eng.getCFG().isBlkExpr(Ex), false);
+#endif 
+
       
       // FIXME: Add a flag to the checker where allocations are allowed to fail.      
       if (RE.getKind() == RetEffect::OwnedAllocatedSymbol)
-        St = StateMgr.AddNE(St, Sym, Eng.getBasicVals().getZeroWithPtrWidth());
+        state = state.AddNE(Sym, Eng.getBasicVals().getZeroWithPtrWidth());
       
       break;
     }
@@ -1639,24 +1647,18 @@
       SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
       QualType RetT = GetReturnType(Ex, Eng.getContext());
       
-      GRState StImpl = *St;
-      RefBindings B = GetRefBindings(StImpl);
-      SetRefBindings(StImpl, RefBFactory.Add(B, Sym,
-                                             RefVal::makeNotOwned(RetT)));
-      
-      St = StateMgr.SetRVal(StateMgr.getPersistentState(StImpl),
-                            Ex, lval::SymbolVal(Sym),
+      state = state.set<RefBindings>(Sym, RefVal::makeNotOwned(RetT), RefBFactory);
+      state = state.SetRVal(Ex, lval::SymbolVal(Sym),
                             Eng.getCFG().isBlkExpr(Ex), false);
-      
       break;
     }
   }
   
   // Is this a sink?
   if (IsEndPath(Summ))
-    Builder.MakeSinkNode(Dst, Ex, Pred, St);
+    Builder.MakeSinkNode(Dst, Ex, Pred, state);
   else
-    Builder.MakeNode(Dst, Ex, Pred, St);
+    Builder.MakeNode(Dst, Ex, Pred, state);
 }
 
 
@@ -1693,7 +1695,7 @@
     if (isa<lval::SymbolVal>(V)) {
       SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
       
-      if (const RefVal* T  = GetRefBindings(*St).lookup(Sym)) {
+      if (const RefVal* T  = St->get<RefBindings>(Sym)) {
         QualType Ty = T->getType();
         
         if (const PointerType* PT = Ty->getAsPointerType()) {
@@ -1743,24 +1745,16 @@
   
   SymbolID Sym = cast<lval::SymbolVal>(Val).getSymbol();
   
-  if (!GetRefBindings(*St).lookup(Sym))
-    return;
+  GRStateRef state(St, Eng.getStateManager());
   
-  // Nuke the binding.  
-  St = NukeBinding(Eng.getStateManager(), St, Sym);
+  if (!state.get<RefBindings>(Sym))
+    return;
   
-  // Hand of the remaining logic to the parent implementation.
-  GRSimpleVals::EvalStore(Dst, Eng, Builder, E, Pred, St, TargetLV, Val);
-}
+  // Nuke the binding.
+  state = state.remove<RefBindings>(Sym, RefBFactory);
 
-
-const GRState* CFRefCount::NukeBinding(GRStateManager& VMgr,
-                                          const GRState* St,
-                                          SymbolID sid) {
-  GRState StImpl = *St;
-  RefBindings B = GetRefBindings(StImpl);
-  StImpl.CheckerState = RefBFactory.Remove(B, sid).getRoot();
-  return VMgr.getPersistentState(StImpl);
+  // Hand of the remaining logic to the parent implementation.
+  GRSimpleVals::EvalStore(Dst, Eng, Builder, E, Pred, state, TargetLV, Val);
 }
 
 // End-of-path.
@@ -1772,21 +1766,19 @@
   hasLeak = V.isOwned() || 
             ((V.isNotOwned() || V.isReturnedOwned()) && V.getCount() > 0);
 
+  GRStateRef state(St, VMgr);
+
   if (!hasLeak)
-    return NukeBinding(VMgr, St, sid);
-  
-  RefBindings B = GetRefBindings(*St);
-  GRState StImpl = *St;
-  StImpl.CheckerState = RefBFactory.Add(B, sid, V^RefVal::ErrorLeak).getRoot();
+    return state.remove<RefBindings>(sid, RefBFactory);
   
-  return VMgr.getPersistentState(StImpl);
+  return state.set<RefBindings>(sid, V ^ RefVal::ErrorLeak, RefBFactory);
 }
 
 void CFRefCount::EvalEndPath(GRExprEngine& Eng,
                              GREndPathNodeBuilder<GRState>& Builder) {
   
   const GRState* St = Builder.getState();
-  RefBindings B = GetRefBindings(*St);
+  RefBindings B = St->get<RefBindings>();
   
   llvm::SmallVector<SymbolID, 10> Leaked;
   
@@ -1828,7 +1820,7 @@
     
   // FIXME: a lot of copy-and-paste from EvalEndPath.  Refactor.
   
-  RefBindings B = GetRefBindings(*St);
+  RefBindings B = St->get<RefBindings>();
   llvm::SmallVector<SymbolID, 10> Leaked;
   
   for (GRStateManager::DeadSymbolsTy::const_iterator
@@ -1875,27 +1867,23 @@
   Expr* RetE = S->getRetValue();
   if (!RetE) return;
   
-  GRStateManager& StateMgr = Eng.getStateManager();
-  const GRState* St = Builder.GetState(Pred);
-  RVal V = StateMgr.GetRVal(St, RetE);
+  GRStateRef state(Builder.GetState(Pred), Eng.getStateManager());
+  RVal V = state.GetRVal(RetE);
   
   if (!isa<lval::SymbolVal>(V))
     return;
   
   // Get the reference count binding (if any).
   SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
-  RefBindings B = GetRefBindings(*St);
-  const RefVal* T = B.lookup(Sym);
+  const RefVal* T = state.get<RefBindings>(Sym);
   
   if (!T)
     return;
   
-  // Change the reference count.
-  
+  // Change the reference count.  
   RefVal X = *T;  
   
-  switch (X.getKind()) {
-      
+  switch (X.getKind()) {      
     case RefVal::Owned: { 
       unsigned cnt = X.getCount();
       assert (cnt > 0);
@@ -1915,10 +1903,8 @@
   }
   
   // Update the binding.
-
-  GRState StImpl = *St;
-  StImpl.CheckerState = RefBFactory.Add(B, Sym, X).getRoot();        
-  Builder.MakeNode(Dst, S, Pred, StateMgr.getPersistentState(StImpl));
+  state = state.set<RefBindings>(Sym, X, RefBFactory);
+  Builder.MakeNode(Dst, S, Pred, state);
 }
 
 // Assumptions.
@@ -1934,7 +1920,7 @@
   //  too bad since the number of symbols we will track in practice are 
   //  probably small and EvalAssume is only called at branches and a few
   //  other places.
-  RefBindings B = GetRefBindings(*St);
+  RefBindings B = St->get<RefBindings>();
   
   if (B.isEmpty())
     return St;
@@ -1953,14 +1939,14 @@
   if (!changed)
     return St;
   
-  GRState StImpl = *St;
-  StImpl.CheckerState = B.getRoot();
-  return VMgr.getPersistentState(StImpl);
+  GRStateRef state(St, VMgr);
+  state = state.set<RefBindings>(B);
+  return state;
 }
 
-CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
-                                           RefVal V, ArgEffect E,
-                                           RefVal::Kind& hasErr) {
+RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
+                               RefVal V, ArgEffect E,
+                               RefVal::Kind& hasErr) {
   
   // FIXME: This dispatch can potentially be sped up by unifiying it into
   //  a single switch statement.  Opt for simplicity for now.
@@ -2215,8 +2201,8 @@
   const GRState* PrevSt = PrevN->getState();
   const GRState* CurrSt = N->getState();
   
-  CFRefCount::RefBindings PrevB = CFRefCount::GetRefBindings(*PrevSt);
-  CFRefCount::RefBindings CurrB = CFRefCount::GetRefBindings(*CurrSt);
+  RefBindings PrevB = PrevSt->get<RefBindings>();
+  RefBindings CurrB = CurrSt->get<RefBindings>();
   
   const RefVal* PrevT = PrevB.lookup(Sym);
   const RefVal* CurrT = CurrB.lookup(Sym);
@@ -2273,6 +2259,7 @@
   // The typestate has changed.
   
   std::ostringstream os;
+  std::string s;
   
   switch (CurrV.getKind()) {
     case RefVal::Owned:
@@ -2296,7 +2283,8 @@
           os << " retain count.";
       }
       
-      Msg = os.str().c_str();
+      s = os.str();
+      Msg = s.c_str();
       
       break;
       
@@ -2342,7 +2330,6 @@
 static std::pair<ExplodedNode<GRState>*,VarDecl*>
 GetAllocationSite(ExplodedNode<GRState>* N, SymbolID Sym) {
 
-  typedef CFRefCount::RefBindings RefBindings;
   ExplodedNode<GRState>* Last = N;
   
   // Find the first node that referred to the tracked symbol.  We also
@@ -2352,7 +2339,7 @@
   
   while (N) {
     const GRState* St = N->getState();
-    RefBindings B = RefBindings((RefBindings::TreeTy*) St->CheckerState);
+    RefBindings B = St->get<RefBindings>();
     
     if (!B.lookup(Sym))
       break;
@@ -2392,17 +2379,12 @@
   if (!getBugType().isLeak())
     return RangedBugReport::getEndPath(BR, EndN);
 
-  typedef CFRefCount::RefBindings RefBindings;
-
   // Get the retain count.
-
-  unsigned long RetCount = 
-    CFRefCount::GetRefBindings(*EndN->getState()).lookup(Sym)->getCount();
+  unsigned long RetCount = EndN->getState()->get<RefBindings>(Sym)->getCount();
   
   // We are a leak.  Walk up the graph to get to the first node where the
   // symbol appeared, and also get the first VarDecl that tracked object
   // is stored to.
-
   ExplodedNode<GRState>* AllocNode = 0;
   VarDecl* FirstDecl = 0;
   llvm::tie(AllocNode, FirstDecl) = GetAllocationSite(EndN, Sym);
@@ -2434,7 +2416,6 @@
 
   // Look in the *trimmed* graph at the immediate predecessor of EndN.  Does
   // it occur on the same line?
-
   PathDiagnosticPiece::DisplayHint Hint = PathDiagnosticPiece::Above;
   
   assert (!EndN->pred_empty()); // Not possible to have 0 predecessors.

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRState.cpp (original)
+++ cfe/trunk/lib/Analysis/GRState.cpp Thu Aug 14 16:16:54 2008
@@ -178,11 +178,9 @@
 
 const GRState* GRStateManager::getInitialState() {
 
-  GRState StateImpl(EnvMgr.getInitialEnvironment(),
-                       StMgr->getInitialStore(),
-                       GDMFactory.GetEmptyMap(),
-                       CNEFactory.GetEmptyMap(),
-                       CEFactory.GetEmptyMap());
+  GRState StateImpl(EnvMgr.getInitialEnvironment(), StMgr->getInitialStore(),
+                    GDMFactory.GetEmptyMap(), CNEFactory.GetEmptyMap(),
+                    CEFactory.GetEmptyMap());
   
   return getPersistentState(StateImpl);
 }
@@ -307,6 +305,25 @@
   for ( ; Beg != End ; ++Beg) (*Beg)->Print(Out, this, nl, sep);
 }
 
+//===----------------------------------------------------------------------===//
+// Generic Data Map.
+//===----------------------------------------------------------------------===//
+
+void* const* GRState::FindGDM(void* K) const {
+  return GDM.lookup(K);
+}
+
+const GRState* GRStateManager::addGDM(const GRState* St, void* Key, void* Data){  
+  GRState::GenericDataMap M1 = St->getGDM();
+  GRState::GenericDataMap M2 = GDMFactory.Add(M1, Key, Data);
+  
+  if (M1 == M2)
+    return St;
+  
+  GRState NewSt = *St;
+  NewSt.GDM = M2;
+  return getPersistentState(NewSt);
+}
 
 //===----------------------------------------------------------------------===//
 // Queries.





More information about the cfe-commits mailing list