diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp --- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp @@ -51,19 +51,16 @@ class RegionRawOffsetV2 { private: const SubRegion *baseRegion; - SVal byteOffset; - - RegionRawOffsetV2() - : baseRegion(nullptr), byteOffset(UnknownVal()) {} + NonLoc byteOffset; public: RegionRawOffsetV2(const SubRegion *base, NonLoc offset) : baseRegion(base), byteOffset(offset) { assert(base); } - NonLoc getByteOffset() const { return byteOffset.castAs(); } + NonLoc getByteOffset() const { return byteOffset; } const SubRegion *getRegion() const { return baseRegion; } - static RegionRawOffsetV2 computeOffset(ProgramStateRef state, + static std::optional computeOffset(ProgramStateRef state, SValBuilder &svalBuilder, SVal location); @@ -158,16 +155,16 @@ ProgramStateRef state = checkerContext.getState(); SValBuilder &svalBuilder = checkerContext.getSValBuilder(); - const RegionRawOffsetV2 &rawOffset = + const std::optional &rawOffset = RegionRawOffsetV2::computeOffset(state, svalBuilder, location); - if (!rawOffset.getRegion()) + if (!rawOffset) return; - NonLoc ByteOffset = rawOffset.getByteOffset(); + NonLoc ByteOffset = rawOffset->getByteOffset(); // CHECK LOWER BOUND - const MemSpaceRegion *SR = rawOffset.getRegion()->getMemorySpace(); + const MemSpaceRegion *SR = rawOffset->getRegion()->getMemorySpace(); if (!llvm::isa(SR)) { // A pointer to UnknownSpaceRegion may point to the middle of // an allocated region. @@ -188,7 +185,7 @@ // CHECK UPPER BOUND DefinedOrUnknownSVal Size = - getDynamicExtent(state, rawOffset.getRegion(), svalBuilder); + getDynamicExtent(state, rawOffset->getRegion(), svalBuilder); if (auto KnownSize = Size.getAs()) { auto [state_withinUpperBound, state_exceedsUpperBound] = compareValueToThreshold(state, ByteOffset, *KnownSize, svalBuilder); @@ -310,7 +307,7 @@ /// Compute a raw byte offset from a base region. Used for array bounds /// checking. -RegionRawOffsetV2 RegionRawOffsetV2::computeOffset(ProgramStateRef state, +std::optional RegionRawOffsetV2::computeOffset(ProgramStateRef state, SValBuilder &svalBuilder, SVal location) { @@ -324,18 +321,18 @@ if (auto Offset = getValue(offset, svalBuilder).getAs()) return RegionRawOffsetV2(subReg, *Offset); } - return RegionRawOffsetV2(); + return {}; } case MemRegion::ElementRegionKind: { const ElementRegion *elemReg = cast(region); SVal index = elemReg->getIndex(); if (!isa(index)) - return RegionRawOffsetV2(); + return {}; QualType elemType = elemReg->getElementType(); // If the element is an incomplete type, go no further. ASTContext &astContext = svalBuilder.getContext(); if (elemType->isIncompleteType()) - return RegionRawOffsetV2(); + return {}; // Update the offset. offset = addValue(state, @@ -347,14 +344,14 @@ svalBuilder); if (offset.isUnknownOrUndef()) - return RegionRawOffsetV2(); + return {}; region = elemReg->getSuperRegion(); continue; } } } - return RegionRawOffsetV2(); + return {}; } void ento::registerArrayBoundCheckerV2(CheckerManager &mgr) {