Allow EvalBinOpNN to handle expressions of the form $a+$b if $b can be reduced to a constant.

llvm-svn: 110592
This commit is contained in:
Jordy Rose 2010-08-09 20:31:57 +00:00
parent b6511a36b4
commit c6c0fc9164
2 changed files with 37 additions and 4 deletions

View File

@ -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(),

View File

@ -1027,3 +1027,21 @@ float f0(_Complex float x) {
return __real l0 + __imag l0;
}
//===----------------------------------------------------------------------===
// Test that we can reduce symbols to constants whether they are on the left
// or right side of an expression.
//===----------------------------------------------------------------------===
void reduce_to_constant(int x, int y) {
if (x != 20)
return;
int a = x + y;
int b = y + x;
if (y == -20 && a != 0)
(void)*(char*)0; // no-warning
if (y == -20 && b != 0)
(void)*(char*)0; // no-warning
}