diff options
Diffstat (limited to 'clang/lib/Checker/Store.cpp')
-rw-r--r-- | clang/lib/Checker/Store.cpp | 17 |
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()); |