diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-10-01 21:09:19 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-01 21:09:19 +0200 |
| commit | 97cdc8ef4426c9940bf83f4c283edc09ea6041e5 (patch) | |
| tree | 4a21303bede3e7daa6739e4fb533da1ea01bae26 /compiler/rustc_interface/src | |
| parent | 389a399a501a626ebf891ae0bb076c25e325ae64 (diff) | |
| parent | bc3d0722062b8e208ba9096b8445ef69a896ed7d (diff) | |
| download | rust-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
