diff options
| author | Jordy Rose <jediknil@belkadan.com> | 2010-08-09 20:31:57 +0000 |
|---|---|---|
| committer | Jordy Rose <jediknil@belkadan.com> | 2010-08-09 20:31:57 +0000 |
| commit | c6c0fc9164c05979b2791791936aaedf28e90c6d (patch) | |
| tree | e6b368a45d0e70056d042dc46e3c49e63854640c /clang/lib/Checker/SimpleSValuator.cpp | |
| parent | b6511a36b4630f4764d73537d958eab5a5ee11c9 (diff) | |
| download | bcm5719-llvm-c6c0fc9164c05979b2791791936aaedf28e90c6d.tar.gz bcm5719-llvm-c6c0fc9164c05979b2791791936aaedf28e90c6d.zip | |
Allow EvalBinOpNN to handle expressions of the form $a+$b if $b can be reduced to a constant.
llvm-svn: 110592
Diffstat (limited to 'clang/lib/Checker/SimpleSValuator.cpp')
| -rw-r--r-- | clang/lib/Checker/SimpleSValuator.cpp | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/clang/lib/Checker/SimpleSValuator.cpp b/clang/lib/Checker/SimpleSValuator.cpp index 48c8b9a81bd..433c3654fad 100644 --- a/clang/lib/Checker/SimpleSValuator.cpp +++ b/clang/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(), |

