> Clang will now more aggressively use undefined behavior on pointer addition overflow for optimization purposes. For example, a check like ptr + unsigned_offset < ptr will now optimize to false, because ptr + unsigned_offset will cause undefined behavior if it overflows (or advances past the end of the object).
> To avoid pointer addition overflow, it is necessary to perform the addition on integers, for example using (uintptr_t)ptr + unsigned_offset < (uintptr_t)ptr. Sometimes, it is also possible to rewrite checks by only comparing the offset. For example, ptr + offset < end_ptr && ptr + offset >= ptr can be written as offset < (uintptr_t)(end_ptr - ptr).
Sigh
Please clarify again, in which machines does pointer overflow does not work but uintptr overflow works?
In which fsking universe does pretending that "pointer overflow" does not do what it does helps anyone except some language lawyers to feel superior to other people?
> The -fwrapv flag now only makes signed integer overflow well-defined, without affecting pointer overflow, which is controlled by a new -fwrapv-pointer flag. The -fno-strict-overflow flag now implies both -fwrapv and -fwrapv-pointer and as such retains its old meaning.
Ah cool, so you have a "work properly" flag, interesting.
What kind of code would actually be affected by this change? It’s easy to imagine sensible code that depends on signed integer overflow (I’ve written some myself in languages where its behavior is well defined). But how often does one come across sensible code that depends on integer overflow for pointers?
The calculation still works, you just can’t check if there was an overflow. I can imagine maybe doing that on, say, an embedded platform with a 16-bit address space. But this kind of code is going to be vastly less common than code that depends on signed integer overflow.
Can somebody explain what the optimizations are that this enables?
Of course you can optimize away the checks but that doesn't count in my world because people put in these checks to make sure there is no overflow and optimizing them away is just wrong.
But I am sure there are other interesting optimizations that this allows and since I am generally against UB I am curious what those are.
7 comments
[ 3.3 ms ] story [ 25.6 ms ] threadSigh
Please clarify again, in which machines does pointer overflow does not work but uintptr overflow works?
In which fsking universe does pretending that "pointer overflow" does not do what it does helps anyone except some language lawyers to feel superior to other people?
> The -fwrapv flag now only makes signed integer overflow well-defined, without affecting pointer overflow, which is controlled by a new -fwrapv-pointer flag. The -fno-strict-overflow flag now implies both -fwrapv and -fwrapv-pointer and as such retains its old meaning.
Ah cool, so you have a "work properly" flag, interesting.
I was first going to say that this would only apply on embedded devices or kernel code
But note, the problem here is not if overflowing (pointer + offset) points to a valid address, but simply if the calculation works
Though maybe you're right, I guess in modern platforms this almost always never apply and my rant is over the top
Of course you can optimize away the checks but that doesn't count in my world because people put in these checks to make sure there is no overflow and optimizing them away is just wrong.
But I am sure there are other interesting optimizations that this allows and since I am generally against UB I am curious what those are.