diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-12-24 08:39:33 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-12-24 08:39:33 +0000 |
commit | a6b0b96e5376cd9cf182a3e240e0537feed43cde (patch) | |
tree | 99f1677f9c39c2c85dcec745008525cdac11ad62 /lib/StaticAnalyzer/SimpleSValBuilder.cpp | |
parent | 3252134192221e65c937124cc79b97d3b04389ae (diff) |
Add basic support for pointer arithmetic in
SimpleSValBuilder. This clears up some
false positives emitted by ArrayBoundCheckerV2
due to the lack of support for pointer arithmetic.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122546 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/SimpleSValBuilder.cpp')
-rw-r--r-- | lib/StaticAnalyzer/SimpleSValBuilder.cpp | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/lib/StaticAnalyzer/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/SimpleSValBuilder.cpp index f1a9074b95..a6432121f5 100644 --- a/lib/StaticAnalyzer/SimpleSValBuilder.cpp +++ b/lib/StaticAnalyzer/SimpleSValBuilder.cpp @@ -808,6 +808,11 @@ SVal SimpleSValBuilder::evalBinOpLL(const GRState *state, SVal SimpleSValBuilder::evalBinOpLN(const GRState *state, BinaryOperator::Opcode op, Loc lhs, NonLoc rhs, QualType resultTy) { + + // Special case: rhs is a zero constant. + if (rhs.isZeroConstant()) + return lhs; + // Special case: 'rhs' is an integer that has the same width as a pointer and // we are using the integer location in a comparison. Normally this cannot be // triggered, but transfer functions like those for OSCommpareAndSwapBarrier32 @@ -858,11 +863,39 @@ SVal SimpleSValBuilder::evalBinOpLN(const GRState *state, return loc::ConcreteInt(getBasicValueFactory().getValue(rightI)); } } - - // Delegate remaining pointer arithmetic to the StoreManager. - return state->getStateManager().getStoreManager().evalBinOp(op, lhs, - rhs, resultTy); + // Handle cases where 'lhs' is a region. + if (const MemRegion *region = lhs.getAsRegion()) { + rhs = cast<NonLoc>(convertToArrayIndex(rhs)); + SVal index = UnknownVal(); + const MemRegion *superR = 0; + QualType elementType; + + if (const ElementRegion *elemReg = dyn_cast<ElementRegion>(region)) { + index = evalBinOpNN(state, BO_Add, elemReg->getIndex(), rhs, + getArrayIndexType()); + superR = elemReg->getSuperRegion(); + elementType = elemReg->getElementType(); + } + else if (isa<SubRegion>(region)) { + superR = region; + index = rhs; + if (const PointerType *PT = resultTy->getAs<PointerType>()) { + elementType = PT->getPointeeType(); + } + else { + const ObjCObjectPointerType *OT = + resultTy->getAs<ObjCObjectPointerType>(); + elementType = OT->getPointeeType(); + } + } + + if (NonLoc *indexV = dyn_cast<NonLoc>(&index)) { + return loc::MemRegionVal(MemMgr.getElementRegion(elementType, *indexV, + superR, getContext())); + } + } + return UnknownVal(); } const llvm::APSInt *SimpleSValBuilder::getKnownValue(const GRState *state, |