-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
addr_of!
a static mut
should not require unsafe
#125833
Comments
It has been in general our expressed preference over time that you use |
see #123758 |
Hmm, it seems we don't take into account this around here: rust/compiler/rustc_mir_build/src/check_unsafety.rs Lines 452 to 464 in ada5e2c
Simple fix. I think? |
It seems like #114447 even floats this idea exactly.
Not being able to use I should clarify that I just ran into this when writing some code for a demonstration, so direct replacements aren't exactly applicable. Regardless, I believe the inconsistency stands. |
Hmm, looking at things more closely, I don't see why it's a Deref. That should be an |
#95439 (comment) claims that arithmetic on Maybe something like this causes problems? |
I think that might be just descriptive (of the problem being discussed here). |
well, that was an unexpected THIR desugaring. Expr {
ty: *const bool
temp_lifetime: Some(Node(1))
span: /home/jubilee/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:2203:5: 2203:22 (#4)
kind:
Scope {
region_scope: Node(3)
lint_level: Explicit(HirId(DefId(0:4 ~ static_mut[60a8]::main).3))
value:
Expr {
ty: *const bool
temp_lifetime: Some(Node(1))
span: /home/jubilee/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:2203:5: 2203:22 (#4)
kind:
AddressOf {
mutability: Not
arg:
Expr {
ty: bool
temp_lifetime: Some(Remainder { block: 68, first_statement_index: 0})
span: static_mut.rs:3:41: 3:45 (#0)
kind:
Scope {
region_scope: Node(4)
lint_level: Explicit(HirId(DefId(0:4 ~ static_mut[60a8]::main).4))
value:
Expr {
ty: bool
temp_lifetime: Some(Remainder { block: 68, first_statement_index: 0})
span: static_mut.rs:3:41: 3:45 (#0)
kind:
Deref {
Expr {
ty: *mut bool
temp_lifetime: Some(Remainder { block: 68, first_statement_index: 0})
span: static_mut.rs:3:41: 3:45 (#0)
kind:
StaticRef {
def_id: DefId(0:3 ~ static_mut[60a8]::FLAG)
ty: *mut bool
alloc_id: alloc1
}
}
}
}
}
}
}
}
}
} |
Oh! Oh, I see, the way that this is defined is that naming a |
PR up at #125834 |
I wanted to say that the compiler should fix it by choosing a different lowering for naming |
…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.
Rollup merge of rust-lang#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#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.
…r-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.
I tried this code (playground):
I expected this to compile without adding an
unsafe
block, since the act of getting the address of the static on its own cannot(?) cause Undefined Behavior. Makingaddr_of!
andaddr_of_mut!
safe when used on astatic mut
would make the behavior consistent withUnsafeCell::get
, which has identical safety concerns in a multithreaded environment.Meta
Exists on stable and the nightly version used by playground (2024-05-30).
The text was updated successfully, but these errors were encountered: