Skip to content
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) Handle compatible ptr-to-ptr casts #840

Closed
Tracked by #833
kkysen opened this issue Feb 16, 2023 · 0 comments · Fixed by #839
Closed
Tracked by #833

(c2rust-analyze) Handle compatible ptr-to-ptr casts #840

kkysen opened this issue Feb 16, 2023 · 0 comments · Fixed by #839
Assignees

Comments

@kkysen
Copy link
Contributor

kkysen commented Feb 16, 2023

Currently, c2rust-analyze can't handle ptr-to-ptr casts when the pointee types are different, even when they're compatible/safely transmutable like u8 and i8/c_char. Thus, fixing this is necessary for c2rust transpiled string literal support (#833).

fn cast_only(s: *const u8) {
    s as *const core::ffi::c_char;
}
callgraph traversal order:
  DefId(0:3 ~ string_casts[c5c4]::cast_only)
visit_statement(StorageLive(_2))
visit_statement(StorageLive(_3))
visit_statement(_3 = _1)
rvalue = _1, desc = Project { base: PlaceRef { local: _1, projection: [] }, proj: [] }, base_lty = g0#*const u8[NONE#u8[]]
visit_rvalue(_1), desc = Some(Project { base: PlaceRef { local: _1, projection: [] }, proj: [] })
equate NONE#u8[] = NONE#u8[]
visit_statement(_2 = move _3 as *const i8 (Misc))
thread 'rustc' panicked at 'unexpected pointer type in *const i8', c2rust-analyze/src/context.rs:503:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/d394408fb38c4de61f765a3ed5189d2731a1da91/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/d394408fb38c4de61f765a3ed5189d2731a1da91/library/core/src/panicking.rs:142:14
   2: c2rust_analyze::context::label_no_pointers::{{closure}}
             at ./src/context.rs:503:9
   3: c2rust_analyze::labeled_ty::LabeledTyCtxt<L>::label
             at ./src/labeled_ty.rs:157:21
   4: c2rust_analyze::context::label_no_pointers
             at ./src/context.rs:502:5
   5: c2rust_analyze::context::AnalysisCtxt::type_of_rvalue
             at ./src/context.rs:368:17
   6: c2rust_analyze::dataflow::type_check::TypeChecker::visit_statement
             at ./src/dataflow/type_check.rs:233:30
   7: c2rust_analyze::dataflow::type_check::visit
             at ./src/dataflow/type_check.rs:388:13
   8: c2rust_analyze::dataflow::generate_constraints
             at ./src/dataflow/mod.rs:326:5
   9: c2rust_analyze::run
             at ./src/main.rs:480:45
kkysen added a commit that referenced this issue Feb 16, 2023
…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.
kkysen added a commit that referenced this issue Feb 16, 2023
…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.
kkysen added a commit that referenced this issue Feb 16, 2023
…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.
kkysen added a commit that referenced this issue Feb 16, 2023
…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.
kkysen added a commit that referenced this issue Feb 16, 2023
…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.
@kkysen kkysen self-assigned this Feb 18, 2023
kkysen added a commit that referenced this issue Feb 19, 2023
…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.
kkysen added a commit that referenced this issue Jun 9, 2023
…le types, for now limited to same-sized integers (#839)

- Fixes #840

This introduces the concept of equivalent/compatible/safely transmutable
types:
https://github.com/immunant/c2rust/blob/2915b8d0c71add21dee1f9d540958ea863478212/c2rust-analyze/src/util.rs#L356-L380

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` as `b"" as *const u8 as *const
core::ffi::c_char`, where `c_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 with
`addr_of!`s. Thus, for some of these (where it works), there are
versions with explicit `addr_of!`s that succeed end-to-end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant