aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/SimpleSValuator.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-10-06 01:39:48 +0000
committerTed Kremenek <kremenek@apple.com>2009-10-06 01:39:48 +0000
commitcd8f6ac9b613e1fe962ebf9c87d822ce765275e6 (patch)
tree9571f28a057b3d9bc021e9d6af2ab420fe7da2e6 /lib/Analysis/SimpleSValuator.cpp
parent2e9f652d53346bf7e64c8a12a9ff06b004a3e489 (diff)
Fix: <rdar://problem/7275774> Static analyzer warns about NULL pointer when
adding assert This fix required a few changes: SimpleSValuator: - Eagerly replace a symbolic value with its constant value in EvalBinOpNN when it is constrained to a constant. This allows us to better constant fold values along a path. - Handle trivial case of '<', '>' comparison of pointers when the two pointers are exactly the same. RegionStoreManager: git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83358 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/SimpleSValuator.cpp')
-rw-r--r--lib/Analysis/SimpleSValuator.cpp26
1 files changed, 22 insertions, 4 deletions
diff --git a/lib/Analysis/SimpleSValuator.cpp b/lib/Analysis/SimpleSValuator.cpp
index 52a591927d..2869fabea3 100644
--- a/lib/Analysis/SimpleSValuator.cpp
+++ b/lib/Analysis/SimpleSValuator.cpp
@@ -29,8 +29,8 @@ public:
virtual SVal EvalMinus(NonLoc val);
virtual SVal EvalComplement(NonLoc val);
- virtual SVal EvalBinOpNN(BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs,
- QualType resultTy);
+ virtual SVal EvalBinOpNN(const GRState *state, BinaryOperator::Opcode op,
+ NonLoc lhs, NonLoc rhs, QualType resultTy);
virtual SVal EvalBinOpLL(BinaryOperator::Opcode op, Loc lhs, Loc rhs,
QualType resultTy);
virtual SVal EvalBinOpLN(const GRState *state, BinaryOperator::Opcode op,
@@ -206,7 +206,8 @@ static SVal EvalEquality(ValueManager &ValMgr, Loc lhs, Loc rhs, bool isEqual,
return ValMgr.makeTruthVal(isEqual ? lhs == rhs : lhs != rhs, resultTy);
}
-SVal SimpleSValuator::EvalBinOpNN(BinaryOperator::Opcode op,
+SVal SimpleSValuator::EvalBinOpNN(const GRState *state,
+ BinaryOperator::Opcode op,
NonLoc lhs, NonLoc rhs,
QualType resultTy) {
// Handle trivial case where left-side and right-side are the same.
@@ -342,8 +343,18 @@ SVal SimpleSValuator::EvalBinOpNN(BinaryOperator::Opcode op,
}
}
case nonloc::SymbolValKind: {
+ nonloc::SymbolVal *slhs = cast<nonloc::SymbolVal>(&lhs);
+ SymbolRef Sym = slhs->getSymbol();
+
+ // Does the symbol simplify to a constant?
+ if (Sym->getType(ValMgr.getContext())->isIntegerType())
+ if (const llvm::APSInt *Constant = state->getSymVal(Sym)) {
+ lhs = nonloc::ConcreteInt(*Constant);
+ continue;
+ }
+
if (isa<nonloc::ConcreteInt>(rhs)) {
- return ValMgr.makeNonLoc(cast<nonloc::SymbolVal>(lhs).getSymbol(), op,
+ return ValMgr.makeNonLoc(slhs->getSymbol(), op,
cast<nonloc::ConcreteInt>(rhs).getValue(),
resultTy);
}
@@ -362,6 +373,13 @@ SVal SimpleSValuator::EvalBinOpLL(BinaryOperator::Opcode op, Loc lhs, Loc rhs,
case BinaryOperator::EQ:
case BinaryOperator::NE:
return EvalEquality(ValMgr, lhs, rhs, op == BinaryOperator::EQ, resultTy);
+ case BinaryOperator::LT:
+ case BinaryOperator::GT:
+ // FIXME: Generalize. For now, just handle the trivial case where
+ // the two locations are identical.
+ if (lhs == rhs)
+ return ValMgr.makeTruthVal(false, resultTy);
+ return UnknownVal();
}
}