about summary refs log tree commit diff
path: root/compiler/rustc_interface/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-10-01 21:09:19 +0200
committerGitHub <noreply@github.com>2024-10-01 21:09:19 +0200
commit97cdc8ef4426c9940bf83f4c283edc09ea6041e5 (patch)
tree4a21303bede3e7daa6739e4fb533da1ea01bae26 /compiler/rustc_interface/src
parent389a399a501a626ebf891ae0bb076c25e325ae64 (diff)
parentbc3d0722062b8e208ba9096b8445ef69a896ed7d (diff)
downloadrust-97cdc8ef4426c9940bf83f4c283edc09ea6041e5.tar.gz
rust-97cdc8ef4426c9940bf83f4c283edc09ea6041e5.zip
Rollup merge of #130229 - RalfJung:ptr-offset-unsigned, r=scottmcm
ptr::add/sub: do not claim equivalence with `offset(c as isize)`

In https://github.com/rust-lang/rust/pull/110837, the `offset` intrinsic got changed to also allow a `usize` offset parameter. The intention is that this will do an unsigned multiplication with the size, and we have UB if that overflows -- and we also have UB if the result is larger than `usize::MAX`, i.e., if a subsequent cast to `isize` would wrap. ~~The LLVM backend sets some attributes accordingly.~~

This updates the docs for `add`/`sub` to match that intent, in preparation for adjusting codegen to exploit this UB. We use this opportunity to clarify what the exact requirements are: we compute the offset using mathematical multiplication (so it's no problem to have an `isize * usize` multiplication, we just multiply integers), and the result must fit in an `isize`.
Cc `@rust-lang/opsem` `@nikic`

https://github.com/rust-lang/rust/pull/130239 updates Miri to detect this UB.

`sub` still has some cases of UB not reflected in the underlying intrinsic semantics (and Miri does not catch): when we subtract `usize::MAX`, then after casting to `isize` that's just `-1` so we end up adding one unit without noticing any UB, but actually the offset we gave does not fit in an `isize`. Miri will currently still not complain for such cases:
```rust
fn main() {
    let x = &[0i32; 2];
    let x = x.as_ptr();
    // This should be UB, we are subtracting way too much.
    unsafe { x.sub(usize::MAX).read() };
}
```
However, the LLVM IR we generate here also is UB-free. This is "just" library UB but not language UB.
Cc `@saethlin;` might be worth adding precondition checks against overflow on `offset`/`add`/`sub`?

Fixes https://github.com/rust-lang/rust/issues/130211
Diffstat (limited to 'compiler/rustc_interface/src')
0 files changed, 0 insertions, 0 deletions