-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Description
Consider the following program:
fn main() {
use core::ptr::*;
unsafe { dbg!(replace(null_mut(), ())); }
}This was made a legal program in Rust 1.80, the preconditions state:
dstmust be valid for both reads and writes.dstmust be properly aligned.dstmust point to a properly initialized value of typeT.
This is because in Rust 1.80 the following line was added to valid:
For operations of size zero, every pointer is valid, including the null pointer. The following points are only concerned with non-zero-sized accesses.
Nevertheless, running the above program results in undefined behavior:
error: Undefined Behavior: constructing invalid value: encountered a null reference
--> /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:1227:22
|
1227 | mem::replace(&mut *dst, src)
| ^^^^^^^^^ constructing invalid value: encountered a null reference
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `std::ptr::replace::<()>` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:1227:22: 1227:31
note: inside `main`
--> src/main.rs:3:19
|
3 | unsafe { dbg!(replace(null_mut(), ())); }
| ^^^^^^^^^^^^^^^^^^^^^^^Rather than changing the implementation of core::ptr::replace, or an isolated change to the requirements of core::ptr::replace, I would like to see the change to the definition of a valid pointer for ZSTs reverted, I've expanded more about my thoughts and provided more arguments in this T-opsem zulip thread. In short, I believe that unsoundness similar to the case here in core::ptr::replace will keep happening as long as "dereferencing a pointer" and "reborrowing a pointer" have different requirements (which they do since Rust 1.80).