]> granicus.if.org Git - clang/commitdiff
[analyzer] Refactor: Move symbol_iterator from SVal to SymExpr, use it
authorAnna Zaks <ganna@apple.com>
Tue, 6 Dec 2011 23:12:33 +0000 (23:12 +0000)
committerAnna Zaks <ganna@apple.com>
Tue, 6 Dec 2011 23:12:33 +0000 (23:12 +0000)
for finding dependent symbols for taint.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145986 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
lib/StaticAnalyzer/Checkers/CStringChecker.cpp
lib/StaticAnalyzer/Core/ProgramState.cpp
lib/StaticAnalyzer/Core/RegionStore.cpp
lib/StaticAnalyzer/Core/SVals.cpp
lib/StaticAnalyzer/Core/SymbolManager.cpp

index a6005ffd96b8fa997c60dc4bc058e003d6d5be30..8c541efd6fec75c415a51b1e6f1bf7ea3f956c55 100644 (file)
@@ -143,30 +143,17 @@ public:
   void dumpToStream(raw_ostream &OS) const;
   void dump() const;
 
-  // Iterators.
-  class symbol_iterator {
-    SmallVector<const SymExpr*, 5> itr;
-    void expand();
-  public:
-    symbol_iterator() {}
-    symbol_iterator(const SymExpr *SE);
-
-    symbol_iterator &operator++();
-    SymbolRef operator*();
-
-    bool operator==(const symbol_iterator &X) const;
-    bool operator!=(const symbol_iterator &X) const;
-  };
-
-  symbol_iterator symbol_begin() const {
+  SymExpr::symbol_iterator symbol_begin() const {
     const SymExpr *SE = getAsSymbolicExpression();
     if (SE)
-      return symbol_iterator(SE);
+      return SE->symbol_begin();
     else
-      return symbol_iterator();
+      return SymExpr::symbol_iterator();
   }
 
-  symbol_iterator symbol_end() const { return symbol_iterator(); }
+  SymExpr::symbol_iterator symbol_end() const { 
+    return SymExpr::symbol_end();
+  }
 
   // Implement isa<T> support.
   static inline bool classof(const SVal*) { return true; }
index addc0d398836b719ec63772c599669260adf5672..d47363cc101ddd6e010c1acef4e06bdf8b69ba6e 100644 (file)
@@ -69,6 +69,26 @@ public:
 
   // Implement isa<T> support.
   static inline bool classof(const SymExpr*) { return true; }
+
+  class symbol_iterator {
+    SmallVector<const SymExpr*, 5> itr;
+    void expand();
+  public:
+    symbol_iterator() {}
+    symbol_iterator(const SymExpr *SE);
+
+    symbol_iterator &operator++();
+    const SymExpr* operator*();
+
+    bool operator==(const symbol_iterator &X) const;
+    bool operator!=(const symbol_iterator &X) const;
+  };
+
+  symbol_iterator symbol_begin() const {
+    return symbol_iterator(this);
+  }
+
+  static symbol_iterator symbol_end() { return symbol_iterator(); }
 };
 
 typedef const SymExpr* SymbolRef;
index 6ab98b41870ad9a233531e5dbb52a92f68f753ad..ff9d8689f63425b2b574d6de022e4f963b4b9699 100644 (file)
@@ -1804,8 +1804,8 @@ void CStringChecker::checkLiveSymbols(const ProgramState *state,
        I != E; ++I) {
     SVal Len = I.getData();
 
-    for (SVal::symbol_iterator si = Len.symbol_begin(), se = Len.symbol_end();
-         si != se; ++si)
+    for (SymExpr::symbol_iterator si = Len.symbol_begin(),
+                                  se = Len.symbol_end(); si != se; ++si)
       SR.markInUse(*si);
   }
 }
index 2dafeeee00faba9a9061ffbe92e0e5fc6a664071..a725d381921eab0f5916c7f9e9d9f55158c10f18 100644 (file)
@@ -673,29 +673,21 @@ bool ProgramState::isTainted(SVal V, TaintTagType Kind) const {
 bool ProgramState::isTainted(const SymExpr* Sym, TaintTagType Kind) const {
   if (!Sym)
     return false;
-
-  // TODO: Can we use symbol_iterator (like removeDeadBindingsWorker) here?
-
-  // Check taint on derived symbols.
-  if (const SymbolDerived *SD = dyn_cast<SymbolDerived>(Sym))
-    return isTainted(SD->getParentSymbol(), Kind);
-
-  if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym))
-    return (isTainted(SC->getOperand(), Kind));
-
-  if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(Sym))
-    return isTainted(SIE->getLHS(), Kind);
-
-  if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym))
-    return (isTainted(SSE->getLHS(), Kind) || isTainted(SSE->getRHS(), Kind));
-
-  // Check taint on the current symbol.
-  if (const SymbolData *SymR = dyn_cast<SymbolData>(Sym)) {
-    const TaintTagType *Tag = get<TaintMap>(SymR);
-    return (Tag && *Tag == Kind);
+  
+  // Travese all the symbols this symbol depends on to see if any are tainted.
+  bool Tainted = false;
+  for (SymExpr::symbol_iterator SI = Sym->symbol_begin(), SE =Sym->symbol_end();
+       SI != SE; ++SI) {
+    assert(isa<SymbolData>(*SI));
+    const TaintTagType *Tag = get<TaintMap>(*SI);
+    Tainted = (Tag && *Tag == Kind);
+
+    // If this is a SymbolDerived with a tainted parent, it's also tainted.
+    if (const SymbolDerived *SD = dyn_cast<SymbolDerived>(*SI))
+      Tainted = Tainted || isTainted(SD->getParentSymbol(), Kind);
+    if (Tainted)
+      return true;
   }
-
-  // TODO: Remove llvm unreachable.
-  llvm_unreachable("We do not know show to check taint on this symbol.");
-  return false;
+  
+  return Tainted;
 }
index 4f811dfa733a705de5ac9b551912ee49e275905e..56ce0e13a9af913b8d8d5c7e2310615881b02be3 100644 (file)
@@ -1721,8 +1721,8 @@ void removeDeadBindingsWorker::VisitBinding(SVal V) {
     AddToWorkList(R);
 
   // Update the set of live symbols.
-  for (SVal::symbol_iterator SI=V.symbol_begin(), SE=V.symbol_end();
-       SI!=SE;++SI)
+  for (SymExpr::symbol_iterator SI = V.symbol_begin(), SE = V.symbol_end();
+       SI!=SE; ++SI)
     SymReaper.markLive(*SI);
 }
 
@@ -1810,7 +1810,7 @@ StoreRef RegionStoreManager::removeDeadBindings(Store store,
       SymReaper.maybeDead(SymR->getSymbol());
 
     SVal X = I.getData();
-    SVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
+    SymExpr::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
     for (; SI != SE; ++SI)
       SymReaper.maybeDead(*SI);
   }
index 97e5a1be4c6634c438b01f4a5c30481b40b3cbb7..27d6e3eed191986d12dab18ad9a3b8d2f5dc2510 100644 (file)
@@ -138,54 +138,6 @@ const MemRegion *loc::MemRegionVal::stripCasts() const {
   return R ?  R->StripCasts() : NULL;
 }
 
-bool SVal::symbol_iterator::operator==(const symbol_iterator &X) const {
-  return itr == X.itr;
-}
-
-bool SVal::symbol_iterator::operator!=(const symbol_iterator &X) const {
-  return itr != X.itr;
-}
-
-SVal::symbol_iterator::symbol_iterator(const SymExpr *SE) {
-  itr.push_back(SE);
-  while (!isa<SymbolData>(itr.back())) expand();
-}
-
-SVal::symbol_iterator &SVal::symbol_iterator::operator++() {
-  assert(!itr.empty() && "attempting to iterate on an 'end' iterator");
-  assert(isa<SymbolData>(itr.back()));
-  itr.pop_back();
-  if (!itr.empty())
-    while (!isa<SymbolData>(itr.back())) expand();
-  return *this;
-}
-
-SymbolRef SVal::symbol_iterator::operator*() {
-  assert(!itr.empty() && "attempting to dereference an 'end' iterator");
-  return cast<SymbolData>(itr.back());
-}
-
-void SVal::symbol_iterator::expand() {
-  const SymExpr *SE = itr.back();
-  itr.pop_back();
-
-  if (const SymbolCast *SC = dyn_cast<SymbolCast>(SE)) {
-    itr.push_back(SC->getOperand());
-    return;
-  }
-  if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
-    itr.push_back(SIE->getLHS());
-    return;
-  }
-  else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
-    itr.push_back(SSE->getLHS());
-    itr.push_back(SSE->getRHS());
-    return;
-  }
-
-  llvm_unreachable("unhandled expansion case");
-}
-
 const void *nonloc::LazyCompoundVal::getStore() const {
   return static_cast<const LazyCompoundValData*>(Data)->getStore();
 }
index 02c0a9e36d400f06b80889d25ef93778a996d57f..e79075f4121e9793e50b02571f85f0beedb39bf4 100644 (file)
@@ -94,6 +94,54 @@ void SymbolRegionValue::dumpToStream(raw_ostream &os) const {
   os << "reg_$" << getSymbolID() << "<" << R << ">";
 }
 
+bool SymExpr::symbol_iterator::operator==(const symbol_iterator &X) const {
+  return itr == X.itr;
+}
+
+bool SymExpr::symbol_iterator::operator!=(const symbol_iterator &X) const {
+  return itr != X.itr;
+}
+
+SymExpr::symbol_iterator::symbol_iterator(const SymExpr *SE) {
+  itr.push_back(SE);
+  while (!isa<SymbolData>(itr.back())) expand();
+}
+
+SymExpr::symbol_iterator &SymExpr::symbol_iterator::operator++() {
+  assert(!itr.empty() && "attempting to iterate on an 'end' iterator");
+  assert(isa<SymbolData>(itr.back()));
+  itr.pop_back();
+  if (!itr.empty())
+    while (!isa<SymbolData>(itr.back())) expand();
+  return *this;
+}
+
+SymbolRef SymExpr::symbol_iterator::operator*() {
+  assert(!itr.empty() && "attempting to dereference an 'end' iterator");
+  return cast<SymbolData>(itr.back());
+}
+
+void SymExpr::symbol_iterator::expand() {
+  const SymExpr *SE = itr.back();
+  itr.pop_back();
+
+  if (const SymbolCast *SC = dyn_cast<SymbolCast>(SE)) {
+    itr.push_back(SC->getOperand());
+    return;
+  }
+  if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
+    itr.push_back(SIE->getLHS());
+    return;
+  }
+  else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
+    itr.push_back(SSE->getLHS());
+    itr.push_back(SSE->getRHS());
+    return;
+  }
+
+  llvm_unreachable("unhandled expansion case");
+}
+
 const SymbolRegionValue*
 SymbolManager::getRegionValueSymbol(const TypedValueRegion* R) {
   llvm::FoldingSetNodeID profile;