You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
incorrect UB when when a ! place is constructed (but not loaded!) #117288
changed the title [-]Miri reports UB when when a `!` place is constructed (but not loaded!)[/-][+]UB when when a `!` place is constructed (but not loaded!)[/+]on Oct 27, 2023
-Zunpretty=thir-tree shows a NeverToAny expression. Maybe this has something to do with it?
Yeah that's probably the right trail. MIR building might not even be at fault, the THIR is already wrong since it thinks there's a never value being constructed here. These THIR nodes seem to be constructed from Adjust::NeverToAny; no idea if there's any way to dump those.
Who are the right people to ping for THIR issues...?
changed the title [-]UB when when a `!` place is constructed (but not loaded!)[/-][+]incorrect UB when when a `!` place is constructed (but not loaded!)[/+]on Oct 28, 2023
Well, I can put up a hack to unblock that specifically. As @Nadrieril pointed out, this is actually two different "bugs" in HIR typeck:
#![feature(never_type)]
fn main() {
unsafe {
let x = 3u8;
let x: *const ! = &x as *const u8 as *const _;
let _ /* (1.) */ = *x;
/* (2.) */
}
}
In the above code:
At (1.), we actually do never type fallback to (). Coercing the ! to ()does constitute a read, and therefore is UB.
At (2.), HIR typeck considers the fact that *x evalauted to ! to mean that all following code diverges, and therefore counts the block's type as ! as well.
Only (2.) actually matters for #129248, and if we were to land that PR right now, it would be unsound:
#![feature(never_type)]fnmake_up_a_value<T>() -> T{let x:*const ! = 0as_;&rawconst*x;// Since `*x` is `!`, HIR typeck thinks it diverges and allows the block to coerce to any value.}
I will probably just put up a hack for (2.), since it's basically the only expression1 where this matters. This doesn't fix the let _: ! = *x; case, but that should remain unsafe at least, and therefore just regular UB and not unsound.
Footnotes
Other combinations of HIR, such as match scrutinees that have no reads should also ideally be fixed... but that's really hard to fix I fear. ↩
I would say it is unsound in the sense that the reference doesn't say that this is UB. Admittedly the reference isn't clear on the entire point about let _ only evaluating the place expression, but that's what we've been consistently communicating for a while now and it has informed other decisions as well (around match, for instance).
But fixing one of two bugs is still progress, so that'd still be a great first step. :)
Activity
[-]Miri reports UB when when a `!` place is constructed (but not loaded!)[/-][+]UB when when a `!` place is constructed (but not loaded!)[/+]RalfJung commentedon Oct 27, 2023
Labeling as "unsound" since under the rules that @rust-lang/opsem decided for
*, and how we've been treating_in general, this shouldn't SIGILL.Nadrieril commentedon Oct 27, 2023
Note that this triggers for
!but notenum Void{}so it's likely a type-based special caseRalfJung commentedon Oct 27, 2023
This is already wrong in the initially generated MIR:
If we use
boolinstead we get just aPlaceMention, as we should@cjgillot any idea why we don't just get a
PlaceMentionfor!?bjorn3 commentedon Oct 27, 2023
-Zunpretty=thir-treeshows aNeverToAnyexpression. Maybe this has something to do with it?Nadrieril commentedon Oct 27, 2023
Oh, then this looks like fallback behavior: if I annotate
let _: ! = *x;I only get a "entering unreachable code" errorRalfJung commentedon Oct 27, 2023
Yeah that's also wrong, but different.^^ MIR for that case:
So we get a
PlaceMentionbut then we also get aunreachable...RalfJung commentedon Oct 28, 2023
Yeah that's probably the right trail. MIR building might not even be at fault, the THIR is already wrong since it thinks there's a never value being constructed here. These THIR nodes seem to be constructed from
Adjust::NeverToAny; no idea if there's any way to dump those.Who are the right people to ping for THIR issues...?
[-]UB when when a `!` place is constructed (but not loaded!)[/-][+]incorrect UB when when a `!` place is constructed (but not loaded!)[/+]41 remaining items
LunarLambda commentedon Jun 27, 2024
No this bug is specific to
!. Equivalent code works fine for empty enumsRalfJung commentedon Aug 21, 2024
This is now blocking #129248: making
addr_of!(*ptr)a safe operation.compiler-errors commentedon Aug 21, 2024
Well, I can put up a hack to unblock that specifically. As @Nadrieril pointed out, this is actually two different "bugs" in HIR typeck:
In the above code:
(). Coercing the!to()does constitute a read, and therefore is UB.*xevalauted to!to mean that all following code diverges, and therefore counts the block's type as!as well.Only (2.) actually matters for #129248, and if we were to land that PR right now, it would be unsound:
I will probably just put up a hack for (2.), since it's basically the only expression1 where this matters. This doesn't fix the
let _: ! = *x;case, but that should remain unsafe at least, and therefore just regular UB and not unsound.Footnotes
Other combinations of HIR, such as match scrutinees that have no reads should also ideally be fixed... but that's really hard to fix I fear. ↩
RalfJung commentedon Aug 21, 2024
I would say it is unsound in the sense that the reference doesn't say that this is UB. Admittedly the reference isn't clear on the entire point about
let _only evaluating the place expression, but that's what we've been consistently communicating for a while now and it has informed other decisions as well (aroundmatch, for instance).But fixing one of two bugs is still progress, so that'd still be a great first step. :)
Auto merge of rust-lang#129392 - compiler-errors:raw-ref-op-doesnt-di…
Auto merge of rust-lang#129392 - compiler-errors:raw-ref-op-doesnt-di…
Auto merge of rust-lang#129392 - compiler-errors:raw-ref-op-doesnt-di…
Auto merge of rust-lang#129392 - compiler-errors:raw-ref-op-doesnt-di…
Auto merge of rust-lang#129392 - compiler-errors:raw-ref-op-doesnt-di…
Rollup merge of rust-lang#129392 - compiler-errors:raw-ref-op-doesnt-…
Auto merge of rust-lang#129392 - compiler-errors:raw-ref-op-doesnt-di…
Unrolled build for rust-lang#129392