aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp27
1 files changed, 22 insertions, 5 deletions
diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index f09f9696f5ad..94d29d5a6ba3 100644
--- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -360,10 +360,18 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
Loc lhsL = lhs.castAs<nonloc::LocAsInteger>().getLoc();
switch (rhs.getSubKind()) {
case nonloc::LocAsIntegerKind:
+ // FIXME: at the moment the implementation
+ // of modeling "pointers as integers" is not complete.
+ if (!BinaryOperator::isComparisonOp(op))
+ return UnknownVal();
return evalBinOpLL(state, op, lhsL,
rhs.castAs<nonloc::LocAsInteger>().getLoc(),
resultTy);
case nonloc::ConcreteIntKind: {
+ // FIXME: at the moment the implementation
+ // of modeling "pointers as integers" is not complete.
+ if (!BinaryOperator::isComparisonOp(op))
+ return UnknownVal();
// Transform the integer into a location and compare.
// FIXME: This only makes sense for comparisons. If we want to, say,
// add 1 to a LocAsInteger, we'd better unpack the Loc and add to it,
@@ -671,7 +679,7 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
if (SymbolRef rSym = rhs.getAsLocSymbol()) {
// We can only build expressions with symbols on the left,
// so we need a reversible operator.
- if (!BinaryOperator::isComparisonOp(op))
+ if (!BinaryOperator::isComparisonOp(op) || op == BO_Cmp)
return UnknownVal();
const llvm::APSInt &lVal = lhs.castAs<loc::ConcreteInt>().getValue();
@@ -718,9 +726,11 @@ SVal SimpleSValBuilder::evalBinOpLL(ProgramStateRef state,
if (Optional<loc::ConcreteInt> rInt = rhs.getAs<loc::ConcreteInt>()) {
// If one of the operands is a symbol and the other is a constant,
// build an expression for use by the constraint manager.
- if (SymbolRef lSym = lhs.getAsLocSymbol(true))
- return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
-
+ if (SymbolRef lSym = lhs.getAsLocSymbol(true)) {
+ if (BinaryOperator::isComparisonOp(op))
+ return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
+ return UnknownVal();
+ }
// Special case comparisons to NULL.
// This must come after the test if the LHS is a symbol, which is used to
// build constraints. The address of any non-symbolic region is guaranteed
@@ -912,6 +922,10 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
if (rhs.isZeroConstant())
return lhs;
+ // Perserve the null pointer so that it can be found by the DerefChecker.
+ if (lhs.isZeroConstant())
+ return lhs;
+
// We are dealing with pointer arithmetic.
// Handle pointer arithmetic on constant values.
@@ -927,6 +941,8 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
// Offset the increment by the pointer size.
llvm::APSInt Multiplicand(rightI.getBitWidth(), /* isUnsigned */ true);
+ QualType pointeeType = resultTy->getPointeeType();
+ Multiplicand = getContext().getTypeSizeInChars(pointeeType).getQuantity();
rightI *= Multiplicand;
// Compute the adjusted pointer.
@@ -1016,7 +1032,8 @@ SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) {
SVB.getKnownValue(State, nonloc::SymbolVal(S)))
return Loc::isLocType(S->getType()) ? (SVal)SVB.makeIntLocVal(*I)
: (SVal)SVB.makeIntVal(*I);
- return nonloc::SymbolVal(S);
+ return Loc::isLocType(S->getType()) ? (SVal)SVB.makeLoc(S)
+ : nonloc::SymbolVal(S);
}
// TODO: Support SymbolCast. Support IntSymExpr when/if we actually