summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-09-03 01:07:06 +0000
committerTed Kremenek <kremenek@apple.com>2010-09-03 01:07:06 +0000
commit56af4462781d2fcd30dcf9a742cb66400e5e55b7 (patch)
treeb20225639799c876b734021f68f5406116b4151c
parent8046037b8342f46197bbee79df83a54b873ae6e6 (diff)
Support pointer arithmetic in SimpleSValuator involving direct constants.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112932 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Checker/SimpleSValuator.cpp37
1 files changed, 36 insertions, 1 deletions
diff --git a/lib/Checker/SimpleSValuator.cpp b/lib/Checker/SimpleSValuator.cpp
index 7650f09d39..5b48e7cd03 100644
--- a/lib/Checker/SimpleSValuator.cpp
+++ b/lib/Checker/SimpleSValuator.cpp
@@ -833,8 +833,43 @@ SVal SimpleSValuator::EvalBinOpLN(const GRState *state,
}
}
}
+
+ // We are dealing with pointer arithmetic.
+
+ // Handle pointer arithmetic on constant values.
+ if (nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs)) {
+ if (loc::ConcreteInt *lhsInt = dyn_cast<loc::ConcreteInt>(&lhs)) {
+ const llvm::APSInt &leftI = lhsInt->getValue();
+ assert(leftI.isUnsigned());
+ llvm::APSInt rightI(rhsInt->getValue(), /* isUnsigned */ true);
+
+ // Convert the bitwidth of rightI. This should deal with overflow
+ // since we are dealing with concrete values.
+ rightI.extOrTrunc(leftI.getBitWidth());
+
+ // Offset the increment by the pointer size.
+ ASTContext &ctx = ValMgr.getContext();
+ const PointerType *PT = resultTy->getAs<PointerType>();
+ llvm::APSInt Multiplicand(rightI.getBitWidth(), /* isUnsigned */ true);
+ rightI *= Multiplicand;
+
+ // Compute the adjusted pointer.
+ switch (op) {
+ case BO_Add:
+ rightI = leftI + rightI;
+ break;
+ case BO_Sub:
+ rightI = leftI - rightI;
+ break;
+ default:
+ llvm_unreachable("Invalid pointer arithmetic operation");
+ }
+ return loc::ConcreteInt(ValMgr.getBasicValueFactory().getValue(rightI));
+ }
+ }
+
- // Delegate pointer arithmetic to the StoreManager.
+ // Delegate remaining pointer arithmetic to the StoreManager.
return state->getStateManager().getStoreManager().EvalBinOp(op, lhs,
rhs, resultTy);
}