-
Notifications
You must be signed in to change notification settings - Fork 13.3k
False positive const-UB check on NonNull
pointer
#133523
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
What's the situation in which you want to do this? The plan is for Or is it just a "please change the error message to say something else"? |
@scottmcm this comes up from doing a sequence of two memory optimizations. The first one is this type. For our purposes we can treat it as a The issue comes up once I wanted to use the low bits of that pointer to additionally bitpack in some more data. So, imagine that I wanted to store a That being said, now that I'm thinking about this though, I don't think that this should be hard to fix - it should be completely fine to replace the |
Yeah we could make our null-check logic more complicated to account for this. That would immediately become a stable guarantee though, now that |
#133700 should fix this :) |
Rollup merge of rust-lang#133700 - RalfJung:const-non-null, r=lcnr const-eval: detect more pointers as definitely not-null This fixes rust-lang#133523 by making the `scalar_may_be_null` check smarter: for instance, an odd offset in any 2-aligned allocation can never be null, even if it is out-of-bounds. More generally, if an allocation with unknown base address B is aligned to alignment N, and a pointer is at offset X inside that allocation, then we know that `(B + X) mod N = B mod N + X mod N = X mod N`. Since `0 mod N` is definitely 0, if we learn that `X mod N` is *not* 0 we can deduce that `B + X` is not 0. This is immediately visible on stable, via `ptr.is_null()` (and, more subtly, by not raising a UB error when such a pointer is used somewhere that a non-null pointer is required). Therefore nominating for `@rust-lang/lang.`
I tried this code:
I expected to see this happen: Compiles. This code cannot be UB, as the alignment on the static guarantees that the produced pointer has odd address and therefore is non-null.
Instead, this happened:
The check seems to know that it might sometimes be wrong, but this isn't a case where the rules around UB are unclear - the rules around what pointers you can put in a
NonNull
are very clear.Meta
All versions of Rust since 1.61 where the necessary operations were stabilized in const
The text was updated successfully, but these errors were encountered: