================
@@ -595,27 +650,86 @@ void ArrayBoundChecker::performCheck(const Expr *E,
CheckerContext &C) const {
auto [Reg, ByteOffset] = *RawOffset;
- // The state updates will be reported as a single note tag, which will be
- // composed by this helper class.
- StateUpdateReporter SUR(Reg, ByteOffset, E, C);
+ const MemSpaceRegion *Space = Reg->getMemorySpace(State);
+ auto Extent = getDynamicExtent(State, Reg, SVB).getAs<NonLoc>();
+
+ // A symbolic region in unknown space represents an unknown pointer that
+ // may point into the middle of an array, so we don't look for underflows.
+ // Both conditions are significant because we want to check underflows in
+ // symbolic regions on the heap (which may be introduced by checkers like
+ // MallocChecker that call SValBuilder::getConjuredHeapSymbolVal()) and
+ // non-symbolic regions (e.g. a field subregion of a symbolic region) in
+ // unknown space.
+
+ bounds::CheckFlags Flags = {
+ /*CheckUnderflow=*/!(isa<SymbolicRegion>(Reg) &&
+ isa<UnknownSpaceRegion>(Space)),
+ /*OffsetObviouslyNonnegative=*/isOffsetObviouslyNonnegative(E, C),
+ /*AcceptPastTheEnd=*/isa<ArraySubscriptExpr>(E) &&
+ isInAddressOf(E, C.getASTContext()),
+ };
+
+ bounds::CheckResult Res = checkBounds(State, SVB, ByteOffset, Extent, Flags);
+
+ if (Res.isCorruptedState()) {
+ C.addSink();
+ return;
+ }
+
+ std::string RegName = getRegionName(Space, Reg);
+
+ const NoteTag *T = nullptr;
+ if (Res.mayBeInvalid()) {
+ if (!Res.mayBeValid()) {
+ SizeUnit SU = SizeUnit::forSVal(Location, C.getASTContext());
+ BugDescription Desc = describeInvalidAccess(Res, RegName, SU);
+ reportOOB(C, State, Desc, ByteOffset, Res.getExtentIfRelevant());
+ return;
+ }
+
+ // FIXME: Remove `Res.mayOverflow()` and provide diagnostics for the case
+ // when the tainted access operation cannot overflow but can underflow.
+ // (This is an NFC commit, so I cannot include this improvement.)
+ if (Res.mayOverflow() && isTainted(State, ByteOffset)) {
+ // Diagnostic detail: saying "tainted offset" is always correct, but
+ // the common case is that 'idx' is tainted in 'arr[idx]' and then it's
+ // nicer to say "tainted index".
+ const char *OffsetName = "offset";
----------------
NagyDonat wrote:
Done in
https://github.com/llvm/llvm-project/pull/210774/commits/e0cc1186cce93b7254028c7c6fefcc2a58a716d6
https://github.com/llvm/llvm-project/pull/210774
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits