aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/GRState.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-09-03 01:06:58 +0000
committerTed Kremenek <kremenek@apple.com>2010-09-03 01:06:58 +0000
commit124f5d5fa4c6b348b4ca5876762fc5eb3864a39b (patch)
tree01699ca8ab7fe4cc90ccb5a4fcd1d03196a7e7a5 /lib/Checker/GRState.cpp
parent4462ee2f0000e6cb966e3fff4516c84292f0cce8 (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
Diffstat (limited to 'lib/Checker/GRState.cpp')
-rw-r--r--lib/Checker/GRState.cpp36
1 files changed, 36 insertions, 0 deletions
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,