-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
rustc: don't use Abi::ScalarPair for unions when padding is involved. #62298
Conversation
The implementation seems fine but I’m not too pumped about the test. It seems like an extremely convulted way to test what’s being tested. I’m partial to codegen tests and there should probably also be a test which checks that |
@nagisa The annoying thing about a codegen test is that the calling conventions can make the code wildly different, and if you rely on optimizations to normalize things, the bug can disappear. FWIW, I've updated the test since, to be more thorough (it now tests both Rust and C ABIs, with more types, and every byte of every type is checked). Also, ideally, I'd use something like the proposed LLVM instruction |
Note that this is by no means a settled matter and people shouldn't start assuming it is. It seems to me that having the optimizations rather than disabling them is good in terms of having people not assume things because they just "seems to work". (In general, I think where rustc can be aggressive while preserving soundness, it should -- but that is not to say that this is easy.) |
The way I see it, this is part of an experiment to see if the semantics of unions being a bag of bytes is even achievable. |
|
||
fn main() { | ||
// NOTE(eddyb) we can't error for the `extern "C"` ABI in these cases, as | ||
// the x86_64 SysV calling convention will drop padding bytes inside unions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is there no .stderr
file then if we expect warnings to be shown?
Also, would be nice to still test the first N bytes that we assume not to be part of the padding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we capture runtime stderr, only rustc stderr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not to mention that only some targets will hit that.
@RalfJung I do like experimentation and data gathering! :) Could we perhaps add some explicit disclaimers around the code and the tests however to make the experimental nature clearer? |
Sure, that seems fair. |
So, considering rust-lang/unsafe-code-guidelines#156, do we still want to do this? |
I honestly don't know.^^ @eddyb @gnzlbg what difference does this make for rust-lang/unsafe-code-guidelines#156 ? |
Without this PR, This means that code that assumes that these bytes are copied on move is broken. This is more restrictive than copying these bytes, and I think it is the conservative thing to do until rust-lang/unsafe-code-guidelines#156 is resolved. That is, I'd rather not merge this. For I think all of this should inform rust-lang/unsafe-code-guidelines#156 , but we should pick there the semantics that make most sense for Rust first, and worry about how to implement them later. |
I'd love to do that, and fight fiercely for "bag of bits no matter the |
Ping from triage: any updates? @eddyb |
This PR is sort-of blocked on the discussion of unions and paddings, and that discussion is currently stalled. We should probably close this PR and revisit when that discussion is settled. @RalfJung what do you think? |
I don't have a good handle on the union situation. Does rust-lang/unsafe-code-guidelines#156 mean we already know the result of the experiment? But anyway this PR only affects IIRC @eddyb mentioned another experiment where we basically add a |
My understanding was that the main concern is that the desired "unions are bags of bits without padding" is not implementable at all, not just because C code may stomp over parts it considers padding, but also because some C ABIs (which pure Rust programs can use without any FFI or |
Ah, right. Yes. So an option might be to make I think we also nee more data on what exactly does (not) get preserved for unions with more than one variant in C. |
Ping from Triage: Closing due to inactivity @eddyb. Looks like changes or updates could still be in the works at some point. If so, please re-open when there are changes or updates. Thanks! |
See #60405 (comment) for the discussion (no issue was opened for that bug).
Assuming that we want to treat unions as opaque bags of bytes and preserve all of them uniformly, this PR disables the "scalar pair" optimization when it would cause some of those bytes to be ignored.
In the example given by @gnzlbg,
(u8, u32)
, bytes1
,2
and3
are interior padding andAbi::ScalarPair
, even if treated as aggregate by non-Rust calling conventions, will cause Rust copies of the whole value to only copy theu8
andu32
components separately, losing the original values in those 3 padding bytes (effectively replacing them withundef
).r? @rkruppe or @nagisa cc @RalfJung