From ba8752aac8e1e59f6bcbb63ccb7fb8f993a19021 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 3 Sep 2010 01:07:06 +0000 Subject: Support pointer arithmetic in SimpleSValuator involving direct constants. llvm-svn: 112932 --- clang/lib/Checker/SimpleSValuator.cpp | 37 ++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'clang/lib/Checker/SimpleSValuator.cpp') 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(&rhs)) { + if (loc::ConcreteInt *lhsInt = dyn_cast(&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(); + 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); } -- cgit v1.2.3