On Mon, Nov 22, 2021 at 03:41:57PM +0530, Siddhesh Poyarekar wrote: > So I played around a bit with this. Basically: > > char buf[8]; > > __SIZE_TYPE__ test (void) > { > char *p = &buf[0x90000004]; > return __builtin_object_size (p + 2, 0); > } > > when built with -m32 returns 0x70000002 but on 64-bit, returns 0 as > expected. of course, with subscript as 0x9000000000000004, 64-bit gives > 0x7000000000000002 as the result.
That is one case, I think when the base is a ADDR_EXPR VAR_DECL, offsets larger than half of the address space will be UB, though of course the question is what __bos should return for that because it wants to prevent UB exploiting. Another case is where the base is some pointer, something like &MEM_REF [ptr, -16].a etc., where the MEM_REF offset negative makes a lot of sense, there could be ptr = &var + 32; earlier etc. That gives us to the general question on what to do with POINTER_PLUS_EXPR if the offset is constant but "negative" (as it is sizetype, it is never negative, but usually we treat it or should treat it as signed in the end). If the offset is "negative", for e.g. __bos 0/1 one option is to use a conservative maximum, i.e. subtract the offset from the value (make it even larger, of course make sure it doesn't wrap around). Another one would be to consider also __bos 2 in that case, if the negation of the offset is bigger than __bos 2, then the pointer points to before the start of the object and we could return 0. Jakub