-
Notifications
You must be signed in to change notification settings - Fork 356
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
Missed UB around assignments and function calls when using custom MIR #2927
Comments
MIR building currently defensively emits a copy basically everywhere. MIR optimizations may allow observing move operands though depending on which ones have been enabled right now. And I hope that in the future we can stop emitting copies as aggresively during MIR building as it reduces effectivity of MIR optimizations, hurts perf for unoptimized builds and even somewhat (and even a lot in some cases) for fully optimized builds. memcpy is used for all assignments of non-primitive types. Function returns work either using registers or a return value pointer which allows the callee to directly write to the return place of the caller's frame. Copy function arguments are copied to a temporary if they are by-ref. Move function arguments directly pass a pointer to the place of the move operand. |
How does an operand being move affect codegen / MIR optimizations (outside of fn calls)?
What exactly is "primitive" here? Is this about having an Aggregate ABI? |
Codegen doesn't distinguish between copy and move in assignments. Only for function calls is it special cased.
Yes, I believe so. |
I guess I could implement the reborrow-based approach outlined here and only use it for aggregate ABI assignments to make sure we check what codegen needs, but that feels very arbitrary. Elsewhere you said once that this affects only some rvalue expressions -- is that based on the observation that e.g. Do you know where in codegen this decision is made? I found this which looks promising. The decision whether to use |
rust-lang/rust#113441 should fix the situation with assignments. |
@bjorn3 if you could take a look at the tests added in rust-lang/rust#113569 and whether they reflect all the UB we need for |
miri: protect Move() function arguments during the call This gives `Move` operands a meaning specific to function calls: - for the duration of the call, the place the operand comes from is protected, making all read and write accesses insta-UB. - the contents of that place are reset to `Uninit`, so looking at them again after the function returns, we cannot observe their contents Turns out we can replace the existing "retag return place" hack with the exact same sort of protection on the return place, which is nicely symmetric. Fixes rust-lang/rust#112564 Fixes rust-lang#2927 This starts with a Miri rustc-push, since we'd otherwise conflict with a PR that recently landed in Miri. (The "miri tree borrows" commit is an unrelated cleanup I noticed while doing the PR. I can remove it if you prefer.) r? `@oli-obk`
miri: protect Move() function arguments during the call This gives `Move` operands a meaning specific to function calls: - for the duration of the call, the place the operand comes from is protected, making all read and write accesses insta-UB. - the contents of that place are reset to `Uninit`, so looking at them again after the function returns, we cannot observe their contents Turns out we can replace the existing "retag return place" hack with the exact same sort of protection on the return place, which is nicely symmetric. Fixes rust-lang/rust#112564 Fixes rust-lang/miri#2927 This starts with a Miri rustc-push, since we'd otherwise conflict with a PR that recently landed in Miri. (The "miri tree borrows" commit is an unrelated cleanup I noticed while doing the PR. I can remove it if you prefer.) r? `@oli-obk`
There are some open questions around assignments and function calls:
move
operands? unsafe-code-guidelines#416When writing custom MIR, Miri currently definitely misses some UB here due to ignoring those questions. For function calls, we have examples of that. For assignments, I am not entirely sure what the current status is -- if I understood @bjorn3 correctly, we do use
memcpy
for some kinds of assignments, so it should be possible to write MIR that is accepted by Miri but UB in LLVM? I hope this requires custom MIR, or can something like that be written in surface Rust?The text was updated successfully, but these errors were encountered: