diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2022-05-21 11:39:50 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-21 11:39:50 +0200 |
| commit | 6fef5f1e243c30deec7728616cdcf21c4547ab9e (patch) | |
| tree | d4240968f37b082ffb5261b45d0cdce26181e239 | |
| parent | e5c7b21f395d57e870eb90292726d0824a34cd10 (diff) | |
| parent | 31c3c0449807d22a0f10e7a290a8e4ed114b98d4 (diff) | |
| download | rust-6fef5f1e243c30deec7728616cdcf21c4547ab9e.tar.gz rust-6fef5f1e243c30deec7728616cdcf21c4547ab9e.zip | |
Rollup merge of #97219 - RalfJung:ptr-invalid, r=thomcc
make ptr::invalid not the same as a regular int2ptr cast
In Miri, we would like to distinguish `ptr::invalid` from `ptr::from_exposed_provenance`, so that we can provide better diagnostics issues like https://github.com/rust-lang/miri/issues/2134, and so that we can detect the UB in programs like
```rust
fn main() {
let x = 0u8;
let original_ptr = &x as *const u8;
let addr = original_ptr.expose_addr();
let new_ptr: *const u8 = core::ptr::invalid(addr);
unsafe {
dbg!(*new_ptr);
}
}
```
To achieve that, the two functions need to have different implementations. Currently, both are just `as` casts. We *could* add an intrinsic for this, but it turns out `transmute` already has the right behavior, at least as far as Miri is concerned. So I propose we just use that.
Cc `@Gankra`
| -rw-r--r-- | library/core/src/ptr/mod.rs | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index ba8b0670147..dc229c9ff9b 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -555,7 +555,11 @@ pub const fn null_mut<T>() -> *mut T { #[unstable(feature = "strict_provenance", issue = "95228")] pub const fn invalid<T>(addr: usize) -> *const T { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. - addr as *const T + // We use transmute rather than a cast so tools like Miri can tell that this + // is *not* the same as from_exposed_addr. + // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that + // pointer). + unsafe { mem::transmute(addr) } } /// Creates an invalid mutable pointer with the given address. @@ -582,7 +586,11 @@ pub const fn invalid<T>(addr: usize) -> *const T { #[unstable(feature = "strict_provenance", issue = "95228")] pub const fn invalid_mut<T>(addr: usize) -> *mut T { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. - addr as *mut T + // We use transmute rather than a cast so tools like Miri can tell that this + // is *not* the same as from_exposed_addr. + // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that + // pointer). + unsafe { mem::transmute(addr) } } /// Convert an address back to a pointer, picking up a previously 'exposed' provenance. |
