-
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
(c2rust-analyze
) Support ptr-to-ptr casts between safely transmutable types, for now limited to same-sized integers
#839
Conversation
fa98935
to
88babe2
Compare
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.
LGTM.
a7f06c4
to
19d0dac
Compare
255a8be
to
d78b925
Compare
@aneksteind, I realized I missed the recursive case here, where |
…le types, for now limited to same-sized integers. This introduces the concept of equivalent/compatible/safely transmutable types. This forms an equivalence class among types, as the safe transmutability must be mutual (i.e. transmutable in both directions; no prefix-transmutability). Thus, we can now allow ptr-to-ptr casts between safely transmutable pointee types, whereas previously they were only allowed for equal types. Equal types could have their `PointerId`s unified as they had the same structure, which is still of safely transmutability types, which are safely transmutability because they have the same structure/layout. As safe transmutability is difficult to check abstractly for any two types, for now we limit it to commonly transmuted types that we know are definitely transmutable: same-sized integer types (with potentially different signedness). Thus, this enables support for string casts like `b"" as *const u8 as *const core::ffi::c_char`, where `c_char = i8`, which fixes #840. Note that the above cast (#833) is still not supported due to the string literal `b""` (#837), but the cast itself (in `string_casts.rs` in `fn cast_only`) works.
…ible/safetly transmutable types, not identical.
… `a ~ b` => `*a ~ *b` for all `a`, `b`).
e665306
to
62ec8dc
Compare
…e-way, now allowing for arrays and slices to decay. This expands the definition of safe transmutability to be one-way. That is, it checks if `*T as *U` is safe, rather than also `*U as *T`. Thus, we can now allow for casts decaying pointers to arrays and slices to pointers to their element type. `do_unify` is modified to also be one-way, which it was already in all call sites. New tests are also added to `string_casts.rs` for all the types of ptr-to-ptr casts. Out of the full string cast, `b"" as *const u8 as *const core::ffi::c_char`, this adds support for the `as *const u8` (from `&[u8; _]`), so only support for the string literal itself remains.
… expanded defintion of safe transmutability.
It seems odd to declare that Also, it would be good to clearly distinguish between the precise logical property, which may be difficult or impossible to check, and the conservative approximation of that property that we use in the implementation. For example, in the trivial functions PR, the precise property is "calls to this function have no effect on pointer permissions in the caller", and the approximation is "there are no raw pointers reachable through the types in this function's signature". The casts allowed by this PR will require some additional library support during rewriting - there's no way to safely convert |
Ptr-to-int transmutes implicitly drop provenance (still being decided) and int-to-ptr transmutes are just UB. They're not safe, and the language I used for this is safe transmutability, so I think we're good here. See rust-lang/unsafe-code-guidelines#286.
I thought I did? Let me check. I at least did in the follow-up PR to this one. I checked. It's in the documentation here.
Wdym by this? This PR doesn't allow that cast, nor anything to do with |
Ah, got it - the official definition is the bit about whether
I haven't read the full thread you linked, but I saw the bit at the end about ptr-to-int transmute dropping provenance, which I believe is the same behavior you get from the safe cast I guess this is a bit of a moot point, since "safely transmutable" is effectively defined in terms of "whatever the Rust devs decide is well-defined".
Sorry, I forgot the example was using |
Yeah.
The ptr-to-int transmute drops provenance, corresponding to See
It is in
|
@spernsteiner, could you take a look at the new separated Also, regarding #909 (comment), I'm not sure why #919 is causing that crash related to pub fn cast_array_to_ptr_explicit(s: &[u8; 0]) {
std::ptr::addr_of!(*s) as *const u8;
} causes thread 'rustc' panicked at 'building TypeDesc for FIXED pointer requires a related pointee type', c2rust-analyze/src/type_desc.rs:75:5 |
I'll investigate that panic next week and also take a look at this PR. |
Fixes the panic described in #839 (comment)
@spernsteiner, I've merged |
…to use well-defined instead of safe and to use "implies" instead of "and".
…rom `{pl,rv}_lty`, as they are interchangeable.
…` to the slice and array rules.
…han `N > 0` to avoid ZSTs, as then the rule would be unsound.
… it's only sound for non-empty slices, but we can't check that at compile-time.
6b3bdd8
to
9b43bd6
Compare
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.
Looks good once the conflict + CI is fixed
@spernsteiner, given #934 is all approved now, if you plan to merge it tomorrow, I'll wait until that merges to rebase/merge this before merging it into |
Actually, there seem to be issues with #934 running on the |
…tring literals in `string_casts.rs` and `lighttpd-minimal`.
…iled string literals in `string_casts.rs` and `lighttpd-minimal`.
c2rust-analyze
) Handle compatible ptr-to-ptr casts #840This introduces the concept of equivalent/compatible/safely transmutable types:
c2rust/c2rust-analyze/src/util.rs
Lines 356 to 380 in 2915b8d
Thus, we can now allow ptr-to-ptr casts between safely transmutable pointee types, whereas previously they were only allowed for equal types. In particular, this enables support for string casts, which are produced by
c2rust transpile
asb"" as *const u8 as *const core::ffi::c_char
, wherec_char = i8
. Thus, this fixes #840.New tests are added in
string_casts.rs
to cover various ptr casts, though some of them crash in the rewriter due to having implicitly inserted MIR statements like implicit&raw
s, which are inserted withaddr_of!
s. Thus, for some of these (where it works), there are versions with explicitaddr_of!
s that succeed end-to-end.