-
Notifications
You must be signed in to change notification settings - Fork 243
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
C without UB is translated to Rust with UB #301
Comments
Sounds like the fix will be non-trivial, if possible at all, since we try to perfectly preserve the semantics and structure (somewhat) of the original C program. Re-borrowing every value after every possible mutation is going to require a lot of additional code and might introduce new bugs. |
Isn't the solution to just do |
I thought so too but that doesn't seem to fix it: |
Personally, I'd bet MIRI just doesn't understand raw references yet. This is the exact problem they were intended to fix, as I understand it. |
@RalfJung what do you think? |
The RFC gives other motivations: taking pointers to unaligned structure fields (which you can't do via an intermediate reference) and to fields in structures at invalid addresses (e.g. at
|
Miri does understand raw pointers. However, Rust has aliasing rules that C does not have, and those are becoming a problem here. Specifically, when you have a local variable
Yes that sounds like the most consistent approach to me -- do that and then never use
That is still mixing raw with non-raw accesses. Here's the "raw-only" version. |
|
Looks like |
Hi @RalfJung! We're noticing some unexpected behavior with miri with regards to We're using this as scaffolding code: use std::ptr::addr_of_mut;
static mut X: i32 = 1;
unsafe fn dec(x: *mut i32) {
*x -= 1;
} And all the examples below are wrapped in
We noticed that this passes miri: let mut x: i32 = 1;
let p = &mut x as *mut i32;
&mut x as *mut i32;
dec(p); but not this: let mut x: i32 = 1;
let p = &mut x as *mut i32;
let _a = &mut x;
dec(p); In the let a = &mut x; // Invalidates `p`
let _b = a as *mut i32; // Seemingly revalidates it why does the
We noticed that while let mut x: i32 = 1;
let p = &mut x as *mut i32;
*addr_of_mut!(x) = 2;
dec(p); it doesn't work for static variables, like this: let p = &mut X as *mut i32;
*addr_of_mut!(X) = 2;
dec(p); Also, for static variables, it works as long as the let p = &mut X as *mut i32;
*addr_of_mut!(X) = 2;
dec(p); doesn't work, but these 3 other orderings do: let p = addr_of_mut!(X);
*addr_of_mut!(X) = 2;
dec(p); let p = addr_of_mut!(X);
*(&mut X as *mut i32) = 2;
dec(p); let p = &mut X as *mut i32;
*(&mut X as *mut i32) = 2;
dec(p); Is this the correct behavior, and if it is, could you explain what exactly is happening? Or is Thanks for all the help! |
Many of your questions, I think, are related to the fact that Miri, by default, treats raw pointers as "untagged". This is necessary to accept a bunch of real-world code out there that does nasty things with integer-pointer casts, but can lead to very surprising behavior. We are actively working on fixing this, but we are not there yet. So, what happens when you run all of your examples with let mut x: i32 = 1;
let p = &mut x as *mut i32;
&mut x as *mut i32;
dec(p); shows
If there is still surprising behavior that you see with this flag, please let me know. :) |
Thanks so much for the help! When I run all the examples with let p = addr_of_mut!(X);
*addr_of_mut!(X) = 2;
dec(p); which is what I was expecting. |
That's great to hear. :) Once rust-lang/miri#2133 is finished, it'd be great if you could test them all again using the default flags; the hope is they should still all behave as you expect then. |
Okay, once rust-lang/miri#2133 lands, I'll re-test all the examples. |
The current plan is to:
|
Try re-generate code using c2rust 0.16, but still have these warnings. Reference issues: c2rust: `https://github.com/immunant/c2rust/issues/301` rust-lang: `https://github.com/rust-lang/rust/issues/82523`
Try re-generate code using c2rust 0.16, but still have these warnings. Reference issues: c2rust: `https://github.com/immunant/c2rust/issues/301` rust-lang: `https://github.com/rust-lang/rust/issues/82523`
translates to
which when run under miri gives:
This happens because the mutable borrow of
f
is invalidated whenf.len
is mutated.The text was updated successfully, but these errors were encountered: