aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/SimpleSValBuilder.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-12-24 08:39:33 +0000
committerTed Kremenek <kremenek@apple.com>2010-12-24 08:39:33 +0000
commita6b0b96e5376cd9cf182a3e240e0537feed43cde (patch)
tree99f1677f9c39c2c85dcec745008525cdac11ad62 /lib/StaticAnalyzer/SimpleSValBuilder.cpp
parent3252134192221e65c937124cc79b97d3b04389ae (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.cpp41
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,