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 | ba8752aac8e1e59f6bcbb63ccb7fb8f993a19021 (patch) | |
| tree | b3cd69ea2e94f0d766539cb3297ed00feefbd27d /clang/lib/Checker/SimpleSValuator.cpp | |
| parent | 5c0969f02744a985d688d68f26764468d4ad9276 (diff) | |
| download | bcm5719-llvm-ba8752aac8e1e59f6bcbb63ccb7fb8f993a19021.tar.gz bcm5719-llvm-ba8752aac8e1e59f6bcbb63ccb7fb8f993a19021.zip | |
Support pointer arithmetic in SimpleSValuator involving direct constants.
llvm-svn: 112932
Diffstat (limited to 'clang/lib/Checker/SimpleSValuator.cpp')
| -rw-r--r-- | clang/lib/Checker/SimpleSValuator.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/clang/lib/Checker/SimpleSValuator.cpp b/clang/lib/Checker/SimpleSValuator.cpp index 7650f09d391..5b48e7cd038 100644 --- a/clang/lib/Checker/SimpleSValuator.cpp +++ b/clang/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); } |

