[llvm] [llvm] Fix __builtin_object_size interaction between Negative Offset … (PR #111827)

Harald van Dijk via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 27 16:59:00 PDT 2024


================
@@ -686,10 +686,23 @@ ObjectSizeOffsetVisitor::ObjectSizeOffsetVisitor(const DataLayout &DL,
 
 SizeOffsetAPInt ObjectSizeOffsetVisitor::compute(Value *V) {
   InstructionsVisited = 0;
-  return computeImpl(V);
+  OffsetSpan Span = computeImpl(V);
+
+  // In ExactSizeFromOffset mode, we don't care about the Before Field, so allow
+  // us to overwrite it if needs be.
+  if (Span.knownAfter() && !Span.knownBefore() &&
+      Options.EvalMode == ObjectSizeOpts::Mode::ExactSizeFromOffset)
+    Span.Before = APInt::getZero(Span.After.getBitWidth());
+
+  if (!Span.bothKnown())
+    return {};
+  if (Span.Before.isNegative() || Span.After.isNegative())
+    return {};
----------------
hvdijk wrote:

Do we need this bit? If this condition is true, we know we have an out of bounds pointer, yet we return that we know nothing about the object's size. I believe if we take this out, the below `return {Span.Before + Span.After, Span.Before};` already handles it correctly and indicates to the caller that we know we have an out of bounds pointer.

A test case for this is

```c++
#include <stdio.h>
int x;
int main() {
  int array[4];
  int *ptr = array + 8;
  printf("%zu\n", __builtin_object_size(ptr, 0));
}
```
Any output is valid, but an output of `0` is best. Previously, we used to print `0`. With your PR, we print `18446744073709551615`. If we take these two lines out, we pass all existing tests, and print `0` again for this new test.

https://github.com/llvm/llvm-project/pull/111827


More information about the llvm-commits mailing list