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

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 24 14:14:47 PDT 2024


serge-sans-paille wrote:

> The problem is not limited to the case where remaining object sizes are equal though, it's just that those are easiest to come up with test cases for. Consider:
> 
> ```c++
> #include <stdio.h>
> int x;
> int main(void) {
>   int array1[4];
>   int array2[8];
>   int *ptr;
>   if (x) {
>     printf("hello\n");
>     ptr = array1 + 1;
>   } else {
>     ptr = array2 + 6;
>   }
>   printf("%zu\n", __builtin_object_size(ptr - 2, 0));
> }
> ```
> 
> This must print 16 or higher, but prints 0 (when optimisations are enabled). During InstCombine `__builtin_object_size` cannot be resolved yet, so instead it is saved for LowerConstantIntrinsics. During LowerConstantIntrinsics, it evaluates with `ObjectSizeOpts::Mode::Max`, sees incoming PHI values {16, 4} and {32, 24}. The former says 12 bytes are available, the latter 8, so it picks the former. Then it applies the negative offset of -8 bytes to it, and because it thinks it knows it's 4 bytes past the start of an object, it wrongly concludes the pointer arithmetic produces an out of bounds value.

Indeed. Looks like my previous approach which propagates the constant (negative) offset would have worked in that situation. But it couldn't work with a dynamic negative offset!
Looks like we should be able to pick different bounds based on the offset sign, I'll explore that path.

In any case, thanks *a lot* for your patience regarding this issue. :bow: 

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


More information about the llvm-commits mailing list