summaryrefslogtreecommitdiffstats
path: root/clang/lib/Checker/Store.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Checker/Store.cpp')
-rw-r--r--clang/lib/Checker/Store.cpp17
1 files changed, 13 insertions, 4 deletions
diff --git a/clang/lib/Checker/Store.cpp b/clang/lib/Checker/Store.cpp
index e0e2c3ad7d3..7c80eed0ead 100644
--- a/clang/lib/Checker/Store.cpp
+++ b/clang/lib/Checker/Store.cpp
@@ -284,10 +284,6 @@ SVal StoreManager::getLValueElement(QualType elementType, SVal Offset,
if (Base.isUnknownOrUndef() || isa<loc::ConcreteInt>(Base))
return Base;
- // Only handle integer offsets... for now.
- if (!isa<nonloc::ConcreteInt>(Offset))
- return UnknownVal();
-
const MemRegion* BaseRegion = cast<loc::MemRegionVal>(Base).getRegion();
// Pointer of any type can be cast and used as array base.
@@ -316,6 +312,19 @@ SVal StoreManager::getLValueElement(QualType elementType, SVal Offset,
return UnknownVal();
const llvm::APSInt& BaseIdxI = cast<nonloc::ConcreteInt>(BaseIdx).getValue();
+
+ // Only allow non-integer offsets if the base region has no offset itself.
+ // FIXME: This is a somewhat arbitrary restriction. We should be using
+ // SValuator here to add the two offsets without checking their types.
+ if (!isa<nonloc::ConcreteInt>(Offset)) {
+ if (isa<ElementRegion>(BaseRegion->StripCasts()))
+ return UnknownVal();
+
+ return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
+ ElemR->getSuperRegion(),
+ Ctx));
+ }
+
const llvm::APSInt& OffI = cast<nonloc::ConcreteInt>(Offset).getValue();
assert(BaseIdxI.isSigned());
OpenPOWER on IntegriCloud