immunant / c2rust

Migrate C code to Rust
https://c2rust.com/
Other
3.91k stars 229 forks source link

(`c2rust-analyze`) Support rewrites with implicit `&raw`s #909

Closed kkysen closed 1 year ago

kkysen commented 1 year ago

Code with implicitly inserted &raws, such as

pub fn cast_array_to_ptr(s: &[u8; 0]) {
    s as *const u8;
}

crashes in the rewriter due to not handling the implicitly inserted &raw in the MIR:

warning: find_primary_location: unsupported expr Expr { hir_id: HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 11 }, kind: Block(Block { stmts: [Stmt { hir_id: HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 9 }, kind: Semi(Expr { hir_id: HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 8 }, kind: Cast(Expr { hir_id: HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 4 }, kind: Path(Resolved(None, Path { span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:5: 36:6 (#0), res: Local(HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 2 }), segments: [PathSegment { ident: s#0, hir_id: Some(HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 3 }), res: Some(Local(HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 2 })), args: None, infer_args: true }] })), span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:5: 36:6 (#0) }, Ty { hir_id: HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 7 }, kind: Ptr(MutTy { ty: Ty { hir_id: HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 5 }, kind: Path(Resolved(None, Path { span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:17: 36:19 (#0), res: PrimTy(Uint(U8)), segments: [PathSegment { ident: u8#0, hir_id: Some(HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 6 }), res: Some(PrimTy(Uint(U8))), args: None, infer_args: false }] })), span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:17: 36:19 (#0) }, mutbl: Not }), span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:10: 36:19 (#0) }), span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:5: 36:19 (#0) }), span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:5: 36:20 (#0) }], expr: None, hir_id: HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 10 }, rules: DefaultBlock, span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:35:39: 37:2 (#0), targeted_by_break: false }, None), span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:35:39: 37:2 (#0) }
warning: find_primary_location: unsupported expr Expr { hir_id: HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 8 }, kind: Cast(Expr { hir_id: HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 4 }, kind: Path(Resolved(None, Path { span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:5: 36:6 (#0), res: Local(HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 2 }), segments: [PathSegment { ident: s#0, hir_id: Some(HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 3 }), res: Some(Local(HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 2 })), args: None, infer_args: true }] })), span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:5: 36:6 (#0) }, Ty { hir_id: HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 7 }, kind: Ptr(MutTy { ty: Ty { hir_id: HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 5 }, kind: Path(Resolved(None, Path { span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:17: 36:19 (#0), res: PrimTy(Uint(U8)), segments: [PathSegment { ident: u8#0, hir_id: Some(HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 6 }), res: Some(PrimTy(Uint(U8))), args: None, infer_args: false }] })), span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:17: 36:19 (#0) }, mutbl: Not }), span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:10: 36:19 (#0) }), span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:5: 36:19 (#0) }
thread 'rustc' panicked at 'bad subexpression index 0 for Expr { hir_id: HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 4 }, kind: Path(Resolved(None, Path { span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:5: 36:6 (#0), res: Local(HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 2 }), segments: [PathSegment { ident: s#0, hir_id: Some(HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 3 }), res: Some(Local(HirId { owner: DefId(0:3 ~ string_casts[c5c4]::cast_array_to_ptr), local_id: 2 })), args: None, infer_args: true }] })), span: /home/kkysen/work/rust/c2rust/c2rust-analyze/tests/analyze/string_casts.rs:36:5: 36:6 (#0) }', c2rust-analyze/src/rewrite/expr/hir_op.rs:244:18

When the &raw is made explicit with an addr_of!, such as

pub fn cast_array_to_ptr_explicit(s: &[u8; 0]) {
    std::ptr::addr_of!(*s) as *const u8;
}

things work again.

Note: These examples are taken from string_casts.rs from #839.

kkysen commented 1 year ago

@spernsteiner, do you think #934 might fix this? I don't want to work on this too much if it's going to be overwritten by #934.

spernsteiner commented 1 year ago

do you think https://github.com/immunant/c2rust/pull/934 might fix this?

I'm not sure. I tried merging together analyze-unlower (#934) and kkysen/analyze-string-casts (#839), but the tests failed, even without adding the example code above. I think the string cast branch is just out of date - merging it with master produces the same error:

thread 'rustc' panicked at 'building TypeDesc for FIXED pointer requires a related pointee type', c2rust-analyze/src/type_desc.rs:75:5
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::type_desc::perms_to_desc
             at ./src/type_desc.rs:75:5
   3: c2rust_analyze::rewrite::expr::mir_op::ExprRewriteVisitor::visit_rvalue
             at ./src/rewrite/expr/mir_op.rs:315:32
   4: c2rust_analyze::rewrite::expr::mir_op::ExprRewriteVisitor::visit_statement::{{closure}}
             at ./src/rewrite/expr/mir_op.rs:214:46
   5: c2rust_analyze::rewrite::expr::mir_op::ExprRewriteVisitor::enter
             at ./src/rewrite/expr/mir_op.rs:104:17
   6: c2rust_analyze::rewrite::expr::mir_op::ExprRewriteVisitor::enter_assign_rvalue
             at ./src/rewrite/expr/mir_op.rs:114:9
   7: c2rust_analyze::rewrite::expr::mir_op::ExprRewriteVisitor::visit_statement
             at ./src/rewrite/expr/mir_op.rs:214:17
   8: c2rust_analyze::rewrite::expr::mir_op::gen_mir_rewrites
             at ./src/rewrite/expr/mir_op.rs:583:13
kkysen commented 1 year ago

Fixed by the refactor in #934.