diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-09-03 01:07:06 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-09-03 01:07:06 +0000 |
commit | 56af4462781d2fcd30dcf9a742cb66400e5e55b7 (patch) | |
tree | b20225639799c876b734021f68f5406116b4151c /lib/Checker/SimpleSValuator.cpp | |
parent | 8046037b8342f46197bbee79df83a54b873ae6e6 (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
Diffstat (limited to 'lib/Checker/SimpleSValuator.cpp')
-rw-r--r-- | lib/Checker/SimpleSValuator.cpp | 37 |
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); } |