Skip to content

Commit

Permalink
[analyzer] Refactor: Move symbol_iterator from SVal to SymExpr, use it
Browse files Browse the repository at this point in the history
for finding dependent symbols for taint.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145986 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
AnnaZaks committed Dec 6, 2011
1 parent aace9ef commit 1d1d515
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 96 deletions.
25 changes: 6 additions & 19 deletions include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
Expand Up @@ -143,30 +143,17 @@ class SVal {
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; }
Expand Down
20 changes: 20 additions & 0 deletions include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
Expand Up @@ -69,6 +69,26 @@ class SymExpr : public llvm::FoldingSetNode {

// 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;
Expand Down
4 changes: 2 additions & 2 deletions lib/StaticAnalyzer/Checkers/CStringChecker.cpp
Expand Up @@ -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);
}
}
Expand Down
40 changes: 16 additions & 24 deletions lib/StaticAnalyzer/Core/ProgramState.cpp
Expand Up @@ -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;
}
6 changes: 3 additions & 3 deletions lib/StaticAnalyzer/Core/RegionStore.cpp
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}
Expand Down
48 changes: 0 additions & 48 deletions lib/StaticAnalyzer/Core/SVals.cpp
Expand Up @@ -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();
}
Expand Down
48 changes: 48 additions & 0 deletions lib/StaticAnalyzer/Core/SymbolManager.cpp
Expand Up @@ -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;
Expand Down

0 comments on commit 1d1d515

Please sign in to comment.