diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-07-23 13:06:54 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-23 13:06:54 +0200 |
| commit | 1b4b0e9a4d00837aa3e96725b13e894d95bb4152 (patch) | |
| tree | 726677269830ab2b944c2bd938f5b480be582113 /src/tools | |
| parent | 49649bf3c5538531ade6834b9b308a6c8a5f3e8e (diff) | |
| parent | b3cd9b5cd3470da7c8f05ed27a8c1db02422b805 (diff) | |
Rollup merge of #125834 - workingjubilee:weaken-thir-unsafeck-for-addr-of-static-mut, r=compiler-errors
treat `&raw (const|mut) UNSAFE_STATIC` implied deref as safe
Fixes rust-lang/rust#125833
As reported in that and related issues, `static mut STATIC_MUT: T` is very often used in embedded code, and is in many ways equivalent to `static STATIC_CELL: SyncUnsafeCell<T>`. The Rust expression of `&raw mut STATIC_MUT` and `SyncUnsafeCell::get(&STATIC_CELL)` are approximately equal, and both evaluate to `*mut T`. The library function is safe because it has *declared itself* to be safe. However, the raw ref operator is unsafe because all uses of `static mut` are considered unsafe, even though the static's value is not used by this expression (unlike, for example, `&STATIC_MUT`).
We can fix this unnatural difference by simply adding the proper exclusion for the safety check inside the THIR unsafeck, so that we do not declare it unsafe if it is not.
While the primary concern here is `static mut`, this change is made for all instances of an "unsafe static", which includes a static declared inside `extern "abi" {}`. Hypothetically, we could go as far as generalizing this to all instances of `&raw (const|mut) *ptr`, but today we do not, as we have not actually considered the range of possible expressions that use a similar encoding. We do not even extend this to thread-local equivalents, because they have less clear semantics.
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/miri/tests/fail/extern_static.rs | 2 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/extern_static.stderr | 4 | ||||
| -rw-r--r-- | src/tools/miri/tests/pass/static_mut.rs | 2 |
3 files changed, 4 insertions, 4 deletions
diff --git a/src/tools/miri/tests/fail/extern_static.rs b/src/tools/miri/tests/fail/extern_static.rs index f8805db8d14..0cbf1646be9 100644 --- a/src/tools/miri/tests/fail/extern_static.rs +++ b/src/tools/miri/tests/fail/extern_static.rs @@ -5,5 +5,5 @@ extern "C" { } fn main() { - let _val = unsafe { std::ptr::addr_of!(FOO) }; //~ ERROR: is not supported by Miri + let _val = std::ptr::addr_of!(FOO); //~ ERROR: is not supported by Miri } diff --git a/src/tools/miri/tests/fail/extern_static.stderr b/src/tools/miri/tests/fail/extern_static.stderr index 21759f96019..c7ab128e2fe 100644 --- a/src/tools/miri/tests/fail/extern_static.stderr +++ b/src/tools/miri/tests/fail/extern_static.stderr @@ -1,8 +1,8 @@ error: unsupported operation: extern static `FOO` is not supported by Miri --> $DIR/extern_static.rs:LL:CC | -LL | let _val = unsafe { std::ptr::addr_of!(FOO) }; - | ^^^ extern static `FOO` is not supported by Miri +LL | let _val = std::ptr::addr_of!(FOO); + | ^^^ extern static `FOO` is not supported by Miri | = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support = note: BACKTRACE: diff --git a/src/tools/miri/tests/pass/static_mut.rs b/src/tools/miri/tests/pass/static_mut.rs index 1b416cc4e9b..4488b5a09d5 100644 --- a/src/tools/miri/tests/pass/static_mut.rs +++ b/src/tools/miri/tests/pass/static_mut.rs @@ -2,7 +2,7 @@ use std::ptr::addr_of; static mut FOO: i32 = 42; -static BAR: Foo = Foo(unsafe { addr_of!(FOO) }); +static BAR: Foo = Foo(addr_of!(FOO)); #[allow(dead_code)] struct Foo(*const i32); |
