================
@@ -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

Reply via email to