diff options
-rw-r--r-- | lib/StaticAnalyzer/Core/ProgramState.cpp | 9 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SymbolManager.cpp | 8 | ||||
-rw-r--r-- | test/Analysis/traversal-path-unification.c | 21 |
3 files changed, 29 insertions, 9 deletions
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp index ed128ef00d..56c6c04df0 100644 --- a/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -106,8 +106,9 @@ ProgramStateManager::removeDeadBindings(ProgramStateRef state, SymReaper); NewState.setStore(newStore); SymReaper.setReapedStore(newStore); - - return getPersistentState(NewState); + + ProgramStateRef Result = getPersistentState(NewState); + return ConstraintMgr->removeDeadBindings(Result, SymReaper); } ProgramStateRef ProgramState::bindCompoundLiteral(const CompoundLiteralExpr *CL, @@ -686,7 +687,9 @@ bool ProgramState::isTainted(SymbolRef Sym, TaintTagType Kind) const { bool Tainted = false; for (SymExpr::symbol_iterator SI = Sym->symbol_begin(), SE =Sym->symbol_end(); SI != SE; ++SI) { - assert(isa<SymbolData>(*SI)); + if (!isa<SymbolData>(*SI)) + continue; + const TaintTagType *Tag = get<TaintMap>(*SI); Tainted = (Tag && *Tag == Kind); diff --git a/lib/StaticAnalyzer/Core/SymbolManager.cpp b/lib/StaticAnalyzer/Core/SymbolManager.cpp index 87b4ba315e..5334b03b3f 100644 --- a/lib/StaticAnalyzer/Core/SymbolManager.cpp +++ b/lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -117,21 +117,17 @@ bool SymExpr::symbol_iterator::operator!=(const symbol_iterator &X) const { 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(); + expand(); return *this; } SymbolRef SymExpr::symbol_iterator::operator*() { assert(!itr.empty() && "attempting to dereference an 'end' iterator"); - return cast<SymbolData>(itr.back()); + return itr.back(); } void SymExpr::symbol_iterator::expand() { diff --git a/test/Analysis/traversal-path-unification.c b/test/Analysis/traversal-path-unification.c new file mode 100644 index 0000000000..0a45f48a01 --- /dev/null +++ b/test/Analysis/traversal-path-unification.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.DumpTraversal %s | FileCheck %s + +int a(); +int b(); +int c(); + +void testRemoveDeadBindings() { + int i = a(); + if (i) + a(); + else + b(); + + // At this point the symbol bound to 'i' is dead. + // The effects of a() and b() are identical (they both invalidate globals). + // We should unify the two paths here and only get one end-of-path node. + c(); +} + +// CHECK: --END PATH-- +// CHECK-NOT: --END PATH--
\ No newline at end of file |