Skip to content

Commit

Permalink
Rollup merge of rust-lang#125834 - workingjubilee:weaken-thir-unsafec…
Browse files Browse the repository at this point in the history
…k-for-addr-of-static-mut, r=compiler-errors

treat `&raw (const|mut) UNSAFE_STATIC` implied deref as safe

Fixes rust-lang#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.
  • Loading branch information
matthiaskrgr authored Jul 23, 2024
2 parents 7ae76f0 + c039ee8 commit ad9a52d
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions panic_unwind/src/seh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,10 @@ mod imp {
// going to be cross-lang LTOed anyway. However, using expose is shorter and
// requires less unsafe.
let addr: usize = ptr.expose_provenance();
#[cfg(bootstrap)]
let image_base = unsafe { addr_of!(__ImageBase) }.addr();
#[cfg(not(bootstrap))]
let image_base = addr_of!(__ImageBase).addr();
let offset: usize = addr - image_base;
Self(offset as u32)
}
Expand Down Expand Up @@ -250,7 +253,10 @@ extern "C" {
// This is fine since the MSVC runtime uses string comparison on the type name
// to match TypeDescriptors rather than pointer equality.
static mut TYPE_DESCRIPTOR: _TypeDescriptor = _TypeDescriptor {
#[cfg(bootstrap)]
pVFTable: unsafe { addr_of!(TYPE_INFO_VTABLE) } as *const _,
#[cfg(not(bootstrap))]
pVFTable: addr_of!(TYPE_INFO_VTABLE) as *const _,
spare: core::ptr::null_mut(),
name: TYPE_NAME,
};
Expand Down

0 comments on commit ad9a52d

Please sign in to comment.