diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-09-03 01:06:58 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-09-03 01:06:58 +0000 |
commit | 124f5d5fa4c6b348b4ca5876762fc5eb3864a39b (patch) | |
tree | 01699ca8ab7fe4cc90ccb5a4fcd1d03196a7e7a5 | |
parent | 4462ee2f0000e6cb966e3fff4516c84292f0cce8 (diff) |
Add GRState::getSimplifiedSVal(), which provides an API hook for doing symbol -> constant folding. This isn't used yet, but
is prep for some pending optimizations in GRExprEngine.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112929 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Checker/PathSensitive/GRState.h | 11 | ||||
-rw-r--r-- | lib/Checker/GRState.cpp | 36 |
2 files changed, 45 insertions, 2 deletions
diff --git a/include/clang/Checker/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h index 984118ea2f..7d998905de 100644 --- a/include/clang/Checker/PathSensitive/GRState.h +++ b/include/clang/Checker/PathSensitive/GRState.h @@ -257,11 +257,18 @@ public: const llvm::APSInt *getSymVal(SymbolRef sym) const; - SVal getSVal(const Stmt* Ex) const; - + /// Returns the SVal bound to the statement 'S' in the state's environment. + SVal getSVal(const Stmt* S) const; + SVal getSValAsScalarOrLoc(const Stmt *Ex) const; SVal getSVal(Loc LV, QualType T = QualType()) const; + + /// Returns a "simplified" SVal bound to the location 'LV' in the state's + /// store. A simplified SVal will include optimizations such as + /// if the SVal is a symbol whose value is perfectly constrained then that + /// constant value is returned instead. + SVal getSimplifiedSVal(Loc LV, QualType T= QualType()) const; SVal getSVal(const MemRegion* R) const; diff --git a/lib/Checker/GRState.cpp b/lib/Checker/GRState.cpp index 024237c8cb..2a7c6dc66e 100644 --- a/lib/Checker/GRState.cpp +++ b/lib/Checker/GRState.cpp @@ -169,6 +169,42 @@ SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const { return UnknownVal(); } +SVal GRState::getSimplifiedSVal(Loc location, QualType T) const { + SVal V = getSVal(cast<Loc>(location), T); + + // If 'V' is a symbolic value that is *perfectly* constrained to + // be a constant value, use that value instead to lessen the burden + // on later analysis stages (so we have less symbolic values to reason + // about). + if (!T.isNull()) { + if (SymbolRef sym = V.getAsSymbol()) { + if (const llvm::APSInt *Int = getSymVal(sym)) { + // FIXME: Because we don't correctly model (yet) sign-extension + // and truncation of symbolic values, we need to convert + // the integer value to the correct signedness and bitwidth. + // + // This shows up in the following: + // + // char foo(); + // unsigned x = foo(); + // if (x == 54) + // ... + // + // The symbolic value stored to 'x' is actually the conjured + // symbol for the call to foo(); the type of that symbol is 'char', + // not unsigned. + const llvm::APSInt &NewV = getBasicVals().Convert(T, *Int); + + if (isa<Loc>(V)) + return loc::ConcreteInt(NewV); + else + return nonloc::ConcreteInt(NewV); + } + } + } + + return V; +} const GRState *GRState::BindExpr(const Stmt* Ex, SVal V, bool Invalidate) const{ Environment NewEnv = getStateManager().EnvMgr.BindExpr(Env, Ex, V, |