[cfe-commits] r65972 - in /cfe/trunk: include/clang/Analysis/PathSensitive/SVals.h include/clang/Analysis/PathSensitive/SymbolManager.h lib/Analysis/BugReporter.cpp lib/Analysis/CFRefCount.cpp lib/Analysis/MemRegion.cpp lib/Analysis/SVals.cpp lib/Analysis/SymbolManager.cpp

Ted Kremenek kremenek at apple.com
Tue Mar 3 14:06:47 PST 2009


Author: kremenek
Date: Tue Mar  3 16:06:47 2009
New Revision: 65972

URL: http://llvm.org/viewvc/llvm-project?rev=65972&view=rev
Log:
Rework use of loc::SymbolVal in the retain/release checker to use the new method
SVal::getAsLocSymbol(). This simplifies the code and allows the retain/release
checker to (I believe) also correctly reason about location symbols wrapped in
SymbolicRegions.

Along the way I cleaned up SymbolRef a little, disallowing implicit casts to
'unsigned'.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
    cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h
    cfe/trunk/lib/Analysis/BugReporter.cpp
    cfe/trunk/lib/Analysis/CFRefCount.cpp
    cfe/trunk/lib/Analysis/MemRegion.cpp
    cfe/trunk/lib/Analysis/SVals.cpp
    cfe/trunk/lib/Analysis/SymbolManager.cpp

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=65972&r1=65971&r2=65972&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h Tue Mar  3 16:06:47 2009
@@ -66,8 +66,7 @@
   inline bool operator==(const SVal& R) const {
     return getRawKind() == R.getRawKind() && Data == R.Data;
   }
-  
-  
+    
   inline bool operator!=(const SVal& R) const {
     return !(*this == R);
   }
@@ -75,7 +74,6 @@
   /// GetRValueSymbolVal - make a unique symbol for value of R.
   static SVal GetRValueSymbolVal(SymbolManager& SymMgr, const MemRegion* R);
 
-  
   inline bool isUnknown() const {
     return getRawKind() == UnknownKind;
   }
@@ -94,6 +92,15 @@
   
   bool isZeroConstant() const;
   
+  /// getAsLocSymbol - If this SVal is a location (subclasses Loc) and 
+  ///  wraps a symbol, return that SymbolRef.  Otherwise return a SymbolRef
+  ///  where 'isValid()' returns false.
+  SymbolRef getAsLocSymbol() const;
+  
+  /// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
+  ///  Otherwise return a SymbolRef where 'isValid()' returns false.
+  SymbolRef getAsSymbol() const;
+  
   void print(std::ostream& OS) const;
   void print(llvm::raw_ostream& OS) const;
   void printStdErr() const;
@@ -237,8 +244,9 @@
 
 class SymbolVal : public NonLoc {
 public:
-  SymbolVal(unsigned SymID)
-    : NonLoc(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
+  SymbolVal(SymbolRef SymID)
+    : NonLoc(SymbolValKind,
+             reinterpret_cast<void*>((uintptr_t) SymID.getNumber())) {}
   
   SymbolRef getSymbol() const {
     return (SymbolRef) reinterpret_cast<uintptr_t>(Data);
@@ -370,8 +378,8 @@
 
 class SymbolVal : public Loc {
 public:
-  SymbolVal(unsigned SymID)
-  : Loc(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID)) {}
+  SymbolVal(SymbolRef SymID)
+  : Loc(SymbolValKind, reinterpret_cast<void*>((uintptr_t) SymID.getNumber())){}
   
   SymbolRef getSymbol() const {
     return (SymbolRef) reinterpret_cast<uintptr_t>(Data);

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=65972&r1=65971&r2=65972&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SymbolManager.h Tue Mar  3 16:06:47 2009
@@ -39,40 +39,45 @@
 public:
   SymbolRef() : Data(~0U - 2) {}
   SymbolRef(unsigned x) : Data(x) {}
-    
-  bool isInitialized() const { return Data != (unsigned) (~0U - 2); }
-  operator unsigned() const { return getNumber(); }
-  unsigned getNumber() const { assert (isInitialized()); return Data; }
+
+  bool isValid() const { return Data != (unsigned) (~0U - 2);  }
+  unsigned getNumber() const { assert (isValid()); return Data; }
   
+  bool operator<(const SymbolRef& X) const { return Data < X.Data; }
+  bool operator>(const SymbolRef& X) const { return Data > X.Data; }
   bool operator==(const SymbolRef& X) const { return Data == X.Data; }
   bool operator!=(const SymbolRef& X) const { return Data != X.Data; }
-    
-  void print(llvm::raw_ostream& os) const;
-  
+      
   void Profile(llvm::FoldingSetNodeID& ID) const { 
-    assert (isInitialized());
+    assert (isValid());
     ID.AddInteger(Data);
   }
 };
-  
 } // end clang namespace
 
 namespace llvm {
-  template <> struct DenseMapInfo<clang::SymbolRef> {
-    static inline clang::SymbolRef getEmptyKey() {
-      return clang::SymbolRef(~0U);
-    }
-    static inline clang::SymbolRef getTombstoneKey() {
-      return clang::SymbolRef(~0U - 1);
-    }
-    static unsigned getHashValue(clang::SymbolRef X) {
-      return X.getNumber();
-    }
-    static bool isEqual(clang::SymbolRef X, clang::SymbolRef Y) {
-      return X.getNumber() == Y.getNumber();
-    }
-    static bool isPod() { return true; }
-  };
+  llvm::raw_ostream& operator<<(llvm::raw_ostream& Out, clang::SymbolRef Sym);
+}
+namespace std {
+  std::ostream& operator<<(std::ostream& Out, clang::SymbolRef Sym);
+}
+
+namespace llvm {
+template <> struct DenseMapInfo<clang::SymbolRef> {
+  static inline clang::SymbolRef getEmptyKey() {
+    return clang::SymbolRef(~0U);
+  }
+  static inline clang::SymbolRef getTombstoneKey() {
+    return clang::SymbolRef(~0U - 1);
+  }
+  static unsigned getHashValue(clang::SymbolRef X) {
+    return X.getNumber();
+  }
+  static bool isEqual(clang::SymbolRef X, clang::SymbolRef Y) {
+    return X == Y;
+  }
+  static bool isPod() { return true; }
+};
 }
 
 // SymbolData: Used to record meta data about symbols.

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

==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Tue Mar  3 16:06:47 2009
@@ -531,7 +531,7 @@
     else
       return true;
   
-    assert (ScanSym.isInitialized());
+    assert (ScanSym.isValid());
   
     if (!BR.isNotable(ScanSym))
       return true;

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

==============================================================================
--- cfe/trunk/lib/Analysis/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Analysis/CFRefCount.cpp Tue Mar  3 16:06:47 2009
@@ -1613,20 +1613,20 @@
   for (ExprIterator I = arg_beg; I != arg_end; ++I, ++idx) {    
     SVal V = state.GetSVal(*I);
     
-    if (isa<loc::SymbolVal>(V)) {
-      SymbolRef Sym = cast<loc::SymbolVal>(V).getSymbol();
+    SymbolRef Sym = V.getAsLocSymbol();
+    if (Sym.isValid())
       if (RefBindings::data_type* T = state.get<RefBindings>(Sym)) {
         state = Update(state, Sym, *T, GetArgE(Summ, idx), hasErr);
         if (hasErr) {
           ErrorExpr = *I;
           ErrorSym = Sym;
           break;
-        }
+        }        
+        continue;
       }
-    }  
-    else if (isa<Loc>(V)) {
-      if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(&V)) {
 
+    if (isa<Loc>(V)) {
+      if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(&V)) {
         if (GetArgE(Summ, idx) == DoNothingByRef)
           continue;
         
@@ -1650,15 +1650,11 @@
           R = dyn_cast<TypedRegion>(ATR->getSuperRegion());
         }
         
-        if (R) {
-          
+        if (R) {          
           // Is the invalidated variable something that we were tracking?
-          SVal X = state.GetSVal(Loc::MakeVal(R));
-          
-          if (isa<loc::SymbolVal>(X)) {
-            SymbolRef Sym = cast<loc::SymbolVal>(X).getSymbol();
+          SymbolRef Sym = state.GetSVal(Loc::MakeVal(R)).getAsLocSymbol();
+          if (Sym.isValid())
             state = state.remove<RefBindings>(Sym);
-          }
           
           // Set the value of the variable to be a conjured symbol.
           unsigned Count = Builder.getCurrentBlockCount();
@@ -1692,9 +1688,8 @@
   
   // Evaluate the effect on the message receiver.  
   if (!ErrorExpr && Receiver) {
-    SVal V = state.GetSVal(Receiver);
-    if (isa<loc::SymbolVal>(V)) {
-      SymbolRef Sym = cast<loc::SymbolVal>(V).getSymbol();
+    SymbolRef Sym = state.GetSVal(Receiver).getAsLocSymbol();
+    if (Sym.isValid()) {
       if (const RefVal* T = state.get<RefBindings>(Sym)) {
         state = Update(state, Sym, *T, GetReceiverE(Summ), hasErr);
         if (hasErr) {
@@ -1831,11 +1826,10 @@
     // FIXME: Wouldn't it be great if this code could be reduced?  It's just
     // a chain of lookups.
     const GRState* St = Builder.GetState(Pred);
-    SVal V = Eng.getStateManager().GetSVal(St, Receiver );
+    SVal V = Eng.getStateManager().GetSVal(St, Receiver);
 
-    if (isa<loc::SymbolVal>(V)) {
-      SymbolRef Sym = cast<loc::SymbolVal>(V).getSymbol();
-      
+    SymbolRef Sym = V.getAsLocSymbol();
+    if (Sym.isValid()) {
       if (const RefVal* T  = St->get<RefBindings>(Sym)) {
         QualType Ty = T->getType();
         
@@ -1979,16 +1973,16 @@
                             ExplodedNode<GRState>* Pred) {
   
   Expr* RetE = S->getRetValue();
-  if (!RetE) return;
+  if (!RetE)
+    return;
   
   GRStateRef state(Builder.GetState(Pred), Eng.getStateManager());
-  SVal V = state.GetSVal(RetE);
+  SymbolRef Sym = state.GetSVal(RetE).getAsLocSymbol();
   
-  if (!isa<loc::SymbolVal>(V))
+  if (!Sym.isValid())
     return;
-  
+
   // Get the reference count binding (if any).
-  SymbolRef Sym = cast<loc::SymbolVal>(V).getSymbol();
   const RefVal* T = state.get<RefBindings>(Sym);
   
   if (!T)
@@ -2461,27 +2455,21 @@
       for (CallExpr::arg_iterator AI=CE->arg_begin(), AE=CE->arg_end();
            AI!=AE; ++AI, ++i) {
         
-        // Retrieve the value of the arugment.
-        SVal X = CurrSt.GetSVal(*AI);
-        
-        // Is it the symbol we're interested in?
-        if (!isa<loc::SymbolVal>(X) || 
-            Sym != cast<loc::SymbolVal>(X).getSymbol())
+        // Retrieve the value of the argument.  Is it the symbol
+        // we are interested in?
+        if (CurrSt.GetSVal(*AI).getAsLocSymbol() != Sym)
           continue;
-        
+
         // We have an argument.  Get the effect!
         AEffects.push_back(Summ->getArg(i));
       }
     }
     else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S)) {      
-      if (Expr *receiver = ME->getReceiver()) {
-        SVal RetV = CurrSt.GetSVal(receiver);        
-        if (isa<loc::SymbolVal>(RetV) &&
-            Sym == cast<loc::SymbolVal>(RetV).getSymbol()) {
+      if (Expr *receiver = ME->getReceiver())
+        if (CurrSt.GetSVal(receiver).getAsLocSymbol() == Sym) {
           // The symbol we are tracking is the receiver.
           AEffects.push_back(Summ->getReceiverEffect());
         }
-      }
     }
   }
   
@@ -2596,14 +2584,11 @@
   // Add the range by scanning the children of the statement for any bindings
   // to Sym.
   for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I!=E; ++I)
-    if (Expr* Exp = dyn_cast_or_null<Expr>(*I)) {
-      SVal X = CurrSt.GetSVal(Exp);      
-      if (loc::SymbolVal* SV = dyn_cast<loc::SymbolVal>(&X))
-        if (SV->getSymbol() == Sym) {
-            P->addRange(Exp->getSourceRange());
-            break;
-        }
-    }
+    if (Expr* Exp = dyn_cast_or_null<Expr>(*I))
+      if (CurrSt.GetSVal(Exp).getAsLocSymbol() == Sym) {
+        P->addRange(Exp->getSourceRange());
+        break;
+      }
   
   return P;
 }
@@ -2619,17 +2604,11 @@
     FindUniqueBinding(SymbolRef sym) : Sym(sym), Binding(0), First(true) {}
     
   bool HandleBinding(StoreManager& SMgr, Store store, MemRegion* R, SVal val) {
-    if (const loc::SymbolVal* SV = dyn_cast<loc::SymbolVal>(&val)) {
-      if (SV->getSymbol() != Sym) 
-        return true;
-    }
-    else if (const nonloc::SymbolVal* SV=dyn_cast<nonloc::SymbolVal>(&val)) {
-      if (SV->getSymbol() != Sym)
-        return true;
-    }
-    else
+    SymbolRef SymV = val.getAsSymbol();
+    
+    if (!SymV.isValid() || SymV != Sym)
       return true;
-
+    
     if (Binding) {
       First = false;
       return false;
@@ -2731,20 +2710,16 @@
       bool foundSymbol = false;
       
       // First check if 'S' itself binds to the symbol.
-      if (Expr *Ex = dyn_cast<Expr>(S)) {
-        SVal X = state.GetSVal(Ex);
-        if (isa<loc::SymbolVal>(X) && 
-            cast<loc::SymbolVal>(X).getSymbol() == Sym)
+      if (Expr *Ex = dyn_cast<Expr>(S))
+        if (state.GetSVal(Ex).getAsLocSymbol() == Sym)
           foundSymbol = true;
-      }
         
       if (!foundSymbol)
         for (Stmt::child_iterator I=S->child_begin(), E=S->child_end();
              I!=E; ++I)
           if (Expr *Ex = dyn_cast_or_null<Expr>(*I)) {
             SVal X = state.GetSVal(Ex);
-            if (isa<loc::SymbolVal>(X) && 
-                cast<loc::SymbolVal>(X).getSymbol() == Sym){
+            if (X.getAsLocSymbol() == Sym) {
               foundSymbol = true;        
               break;
             }
@@ -2848,8 +2823,8 @@
     bool hasLeak = false;
     
     std::pair<GRStateRef, bool> X =
-    HandleSymbolDeath(Eng.getStateManager(), St, CodeDecl,
-                      (*I).first, (*I).second, hasLeak);
+      HandleSymbolDeath(Eng.getStateManager(), St, CodeDecl,
+                        (*I).first, (*I).second, hasLeak);
     
     St = X.first;
     if (hasLeak) Leaked.push_back(std::make_pair((*I).first, X.second));

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

==============================================================================
--- cfe/trunk/lib/Analysis/MemRegion.cpp (original)
+++ cfe/trunk/lib/Analysis/MemRegion.cpp Tue Mar  3 16:06:47 2009
@@ -171,8 +171,7 @@
 }
 
 void SymbolicRegion::print(llvm::raw_ostream& os) const {
-  os << "SymRegion-";
-  sym.print(os);
+  os << "SymRegion-" << sym;
 }
 
 void FieldRegion::print(llvm::raw_ostream& os) const {

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

==============================================================================
--- cfe/trunk/lib/Analysis/SVals.cpp (original)
+++ cfe/trunk/lib/Analysis/SVals.cpp Tue Mar  3 16:06:47 2009
@@ -54,6 +54,42 @@
   return symbol_iterator();
 }
 
+/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and 
+///  wraps a symbol, return that SymbolRef.  Otherwise return a SymbolRef
+///  where 'isValid()' returns false.
+SymbolRef SVal::getAsLocSymbol() const {
+  if (const loc::SymbolVal *X = dyn_cast<loc::SymbolVal>(this))
+    return X->getSymbol();
+
+  if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
+    const MemRegion *R = X->getRegion();
+    
+    while (R) {
+      // Blast through region views.
+      if (const TypedViewRegion *View = dyn_cast<TypedViewRegion>(R)) {
+        R = View->getSuperRegion();
+        continue;
+      }
+      
+      if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
+        return SymR->getSymbol();
+      
+      break;
+    }
+  }
+  
+  return SymbolRef();
+}
+
+/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
+///  Otherwise return a SymbolRef where 'isValid()' returns false.
+SymbolRef SVal::getAsSymbol() const {
+  if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
+    return X->getSymbol();
+  
+  return getAsLocSymbol();
+}
+
 //===----------------------------------------------------------------------===//
 // Other Iterators.
 //===----------------------------------------------------------------------===//

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

==============================================================================
--- cfe/trunk/lib/Analysis/SymbolManager.cpp (original)
+++ cfe/trunk/lib/Analysis/SymbolManager.cpp Tue Mar  3 16:06:47 2009
@@ -18,8 +18,23 @@
 
 using namespace clang;
 
-void SymbolRef::print(llvm::raw_ostream& os) const {
-  os << getNumber();
+llvm::raw_ostream& llvm::operator<<(llvm::raw_ostream& os,
+                                    clang::SymbolRef sym)  {
+  if (sym.isValid())
+    os << sym.getNumber();
+  else
+    os << "(Invalid)";
+  
+  return os;
+}
+
+std::ostream& std::operator<<(std::ostream& os, clang::SymbolRef sym) {
+  if (sym.isValid())
+    os << sym.getNumber();
+  else
+    os << "(Invalid)";
+  
+  return os;
 }
 
 SymbolRef SymbolManager::getRegionRValueSymbol(const MemRegion* R) {  
@@ -35,7 +50,6 @@
   DataSet.InsertNode(SD, InsertPos);
   DataMap[SymbolCounter] = SD;  
   return SymbolCounter++;
-
 }
 
 SymbolRef SymbolManager::getConjuredSymbol(Stmt* E, QualType T, unsigned Count){





More information about the cfe-commits mailing list