diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-01-06 22:09:28 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-01-06 22:09:28 +0000 |
commit | 5eca482fe895ea57bc82410222e6426c09e63284 (patch) | |
tree | 1f0861024b70d405e980c0dcbed9baa0904d0913 /lib/StaticAnalyzer/Core/ProgramState.cpp | |
parent | 0782ef2bd0ef5025ac6512cfa445a80a464c3b7f (diff) |
[analyzer] Make the entries in 'Environment' context-sensitive by making entries map from
(Stmt*,LocationContext*) pairs to SVals instead of Stmt* to SVals.
This is needed to support basic IPA via inlining. Without this, we cannot tell
if a Stmt* binding is part of the current analysis scope (StackFrameContext) or
part of a parent context.
This change introduces an uglification of the use of getSVal(), and thus takes
two steps forward and one step back. There are also potential performance implications
of enlarging the Environment. Both can be addressed going forward by refactoring the
APIs and optimizing the internal representation of Environment. This patch
mainly introduces the functionality upon when we want to build upon (and clean up).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147688 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ProgramState.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ProgramState.cpp | 129 |
1 files changed, 26 insertions, 103 deletions
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp index 4b98ce8b0f..8a287e9e16 100644 --- a/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -239,9 +239,12 @@ SVal ProgramState::getSVal(Loc location, QualType T) const { return V; } -const ProgramState *ProgramState::BindExpr(const Stmt *S, SVal V, bool Invalidate) const{ - Environment NewEnv = getStateManager().EnvMgr.bindExpr(Env, S, V, - Invalidate); +const ProgramState *ProgramState::BindExpr(const Stmt *S, + const LocationContext *LCtx, + SVal V, bool Invalidate) const{ + Environment NewEnv = + getStateManager().EnvMgr.bindExpr(Env, EnvironmentEntry(S, LCtx), V, + Invalidate); if (NewEnv == Env) return this; @@ -250,10 +253,14 @@ const ProgramState *ProgramState::BindExpr(const Stmt *S, SVal V, bool Invalidat return getStateManager().getPersistentState(NewSt); } -const ProgramState *ProgramState::bindExprAndLocation(const Stmt *S, SVal location, - SVal V) const { +const ProgramState * +ProgramState::bindExprAndLocation(const Stmt *S, const LocationContext *LCtx, + SVal location, + SVal V) const { Environment NewEnv = - getStateManager().EnvMgr.bindExprAndLocation(Env, S, location, V); + getStateManager().EnvMgr.bindExprAndLocation(Env, + EnvironmentEntry(S, LCtx), + location, V); if (NewEnv == Env) return this; @@ -380,114 +387,28 @@ void ProgramState::setStore(const StoreRef &newStore) { // State pretty-printing. //===----------------------------------------------------------------------===// -static bool IsEnvLoc(const Stmt *S) { - // FIXME: This is a layering violation. Should be in environment. - return (bool) (((uintptr_t) S) & 0x1); -} - -void ProgramState::print(raw_ostream &Out, CFG *C, +void ProgramState::print(raw_ostream &Out, const char *NL, const char *Sep) const { // Print the store. ProgramStateManager &Mgr = getStateManager(); Mgr.getStoreManager().print(getStore(), Out, NL, Sep); - bool isFirst = true; - - // FIXME: All environment printing should be moved inside Environment. - if (C) { - // Print Subexpression bindings. - for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) { - if (C->isBlkExpr(I.getKey()) || IsEnvLoc(I.getKey())) - continue; - - if (isFirst) { - Out << NL << NL << "Sub-Expressions:" << NL; - isFirst = false; - } else { - Out << NL; - } - Out << " (" << (void*) I.getKey() << ") "; - LangOptions LO; // FIXME. - I.getKey()->printPretty(Out, 0, PrintingPolicy(LO)); - Out << " : " << I.getData(); - } - - // Print block-expression bindings. - isFirst = true; - for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) { - if (!C->isBlkExpr(I.getKey())) - continue; - - if (isFirst) { - Out << NL << NL << "Block-level Expressions:" << NL; - isFirst = false; - } else { - Out << NL; - } - - Out << " (" << (void*) I.getKey() << ") "; - LangOptions LO; // FIXME. - I.getKey()->printPretty(Out, 0, PrintingPolicy(LO)); - Out << " : " << I.getData(); - } - } else { - // Print All bindings - no info to differentiate block from subexpressions. - for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) { - if (IsEnvLoc(I.getKey())) - continue; - - if (isFirst) { - Out << NL << NL << "Expressions:" << NL; - isFirst = false; - } else { - Out << NL; - } - - Out << " (" << (void*) I.getKey() << ") "; - LangOptions LO; // FIXME. - I.getKey()->printPretty(Out, 0, PrintingPolicy(LO)); - Out << " : " << I.getData(); - } - } - - // Print locations. - isFirst = true; - - for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) { - if (!IsEnvLoc(I.getKey())) - continue; - - if (isFirst) { - Out << NL << NL << "Load/store locations:" << NL; - isFirst = false; - } else { - Out << NL; - } - - const Stmt *S = (Stmt*) (((uintptr_t) I.getKey()) & ((uintptr_t) ~0x1)); - - Out << " (" << (void*) S << ") "; - LangOptions LO; // FIXME. - S->printPretty(Out, 0, PrintingPolicy(LO)); - Out << " : " << I.getData(); - } + // Print out the environment. + Env.print(Out, NL, Sep); + // Print out the constraints. Mgr.getConstraintManager().print(this, Out, NL, Sep); // Print checker-specific data. Mgr.getOwningEngine()->printState(Out, this, NL, Sep); } -void ProgramState::printDOT(raw_ostream &Out, CFG &C) const { - print(Out, &C, "\\l", "\\|"); -} - -void ProgramState::dump(CFG &C) const { - print(llvm::errs(), &C); +void ProgramState::printDOT(raw_ostream &Out) const { + print(Out, "\\l", "\\|"); } void ProgramState::dump() const { - print(llvm::errs(), 0); + print(llvm::errs()); } //===----------------------------------------------------------------------===// @@ -654,15 +575,16 @@ bool ProgramState::scanReachableSymbols(const MemRegion * const *I, } const ProgramState* ProgramState::addTaint(const Stmt *S, + const LocationContext *LCtx, TaintTagType Kind) const { if (const Expr *E = dyn_cast_or_null<Expr>(S)) S = E->IgnoreParens(); - SymbolRef Sym = getSVal(S).getAsSymbol(); + SymbolRef Sym = getSVal(S, LCtx).getAsSymbol(); if (Sym) return addTaint(Sym, Kind); - const MemRegion *R = getSVal(S).getAsRegion(); + const MemRegion *R = getSVal(S, LCtx).getAsRegion(); addTaint(R, Kind); // Cannot add taint, so just return the state. @@ -683,11 +605,12 @@ const ProgramState* ProgramState::addTaint(SymbolRef Sym, return NewState; } -bool ProgramState::isTainted(const Stmt *S, TaintTagType Kind) const { +bool ProgramState::isTainted(const Stmt *S, const LocationContext *LCtx, + TaintTagType Kind) const { if (const Expr *E = dyn_cast_or_null<Expr>(S)) S = E->IgnoreParens(); - SVal val = getSVal(S); + SVal val = getSVal(S, LCtx); return isTainted(val, Kind); } |