aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/SimpleSValuator.cpp
diff options
context:
space:
mode:
authorJordy Rose <jediknil@belkadan.com>2010-08-09 20:31:57 +0000
committerJordy Rose <jediknil@belkadan.com>2010-08-09 20:31:57 +0000
commita277e7764bbe2752f900bf595654f9ad433f3961 (patch)
treec14d9951edb82e2e865d46a9634cf21a4d3a3c46 /lib/Checker/SimpleSValuator.cpp
parentd1909bbc8aa8b468527250766c8f4e67379da2d6 (diff)
Allow EvalBinOpNN to handle expressions of the form $a+$b if $b can be reduced to a constant.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110592 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/SimpleSValuator.cpp')
-rw-r--r--lib/Checker/SimpleSValuator.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/lib/Checker/SimpleSValuator.cpp b/lib/Checker/SimpleSValuator.cpp
index 48c8b9a81b..433c3654fa 100644
--- a/lib/Checker/SimpleSValuator.cpp
+++ b/lib/Checker/SimpleSValuator.cpp
@@ -461,10 +461,12 @@ SVal SimpleSValuator::EvalBinOpNN(const GRState *state,
case nonloc::SymbolValKind: {
nonloc::SymbolVal *slhs = cast<nonloc::SymbolVal>(&lhs);
SymbolRef Sym = slhs->getSymbol();
-
+
+ ASTContext& Ctx = ValMgr.getContext();
+
// Does the symbol simplify to a constant? If so, "fold" the constant
// by setting 'lhs' to a ConcreteInt and try again.
- if (Sym->getType(ValMgr.getContext())->isIntegerType())
+ if (Sym->getType(Ctx)->isIntegerType())
if (const llvm::APSInt *Constant = state->getSymVal(Sym)) {
// The symbol evaluates to a constant. If necessary, promote the
// folded constant (LHS) to the result type.
@@ -474,7 +476,7 @@ SVal SimpleSValuator::EvalBinOpNN(const GRState *state,
// Also promote the RHS (if necessary).
- // For shifts, it necessary promote the RHS to the result type.
+ // For shifts, it is not necessary to promote the RHS.
if (BinaryOperator::isShiftOp(op))
continue;
@@ -486,7 +488,20 @@ SVal SimpleSValuator::EvalBinOpNN(const GRState *state,
continue;
}
-
+
+ // Is the RHS a symbol we can simplify?
+ if (const nonloc::SymbolVal *srhs = dyn_cast<nonloc::SymbolVal>(&rhs)) {
+ SymbolRef RSym = srhs->getSymbol();
+ if (RSym->getType(Ctx)->isIntegerType()) {
+ if (const llvm::APSInt *Constant = state->getSymVal(RSym)) {
+ // The symbol evaluates to a constant.
+ BasicValueFactory &BVF = ValMgr.getBasicValueFactory();
+ const llvm::APSInt &rhs_I = BVF.Convert(resultTy, *Constant);
+ rhs = nonloc::ConcreteInt(rhs_I);
+ }
+ }
+ }
+
if (isa<nonloc::ConcreteInt>(rhs)) {
return MakeSymIntVal(slhs->getSymbol(), op,
cast<nonloc::ConcreteInt>(rhs).getValue(),