diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-10-06 01:39:48 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-10-06 01:39:48 +0000 |
commit | cd8f6ac9b613e1fe962ebf9c87d822ce765275e6 (patch) | |
tree | 9571f28a057b3d9bc021e9d6af2ab420fe7da2e6 /lib/Analysis/SimpleSValuator.cpp | |
parent | 2e9f652d53346bf7e64c8a12a9ff06b004a3e489 (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.cpp | 26 |
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(); } } |