Skip to content

Commit

Permalink
analyze: implement calloc rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
spernsteiner committed Aug 6, 2024
1 parent 7c22079 commit 6a091e1
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 13 deletions.
30 changes: 23 additions & 7 deletions c2rust-analyze/src/rewrite/expr/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,17 +290,33 @@ impl<'tcx> ConvertVisitor<'tcx> {
ref zero_ty,
elem_size,
single,
}
| mir_op::RewriteKind::CallocSafe {
ref zero_ty,
elem_size,
single,
} => {
// `malloc(n)` -> `Box::new(z)` or similar
assert!(matches!(hir_rw, Rewrite::Identity));
let zeroize_expr = generate_zeroize_expr(zero_ty);
let mut stmts = vec![
Rewrite::Let(vec![("byte_len".into(), self.get_subexpr(ex, 0))]),
Rewrite::Let1(
"n".into(),
Box::new(format_rewrite!("byte_len as usize / {elem_size}")),
),
];
let mut stmts = match *rw {
mir_op::RewriteKind::MallocSafe { .. } => vec![
Rewrite::Let(vec![("byte_len".into(), self.get_subexpr(ex, 0))]),
Rewrite::Let1(
"n".into(),
Box::new(format_rewrite!("byte_len as usize / {elem_size}")),
),
],
mir_op::RewriteKind::CallocSafe { .. } => vec![
Rewrite::Let(vec![
("count".into(), self.get_subexpr(ex, 0)),
("size".into(), self.get_subexpr(ex, 1)),
]),
format_rewrite!("assert_eq!(size, {elem_size})"),
Rewrite::Let1("n".into(), Box::new(format_rewrite!("count as usize"))),
],
_ => unreachable!(),
};
let expr = if single {
stmts.push(Rewrite::Text("assert_eq!(n, 1)".into()));
format_rewrite!("Box::new({})", zeroize_expr)
Expand Down
26 changes: 20 additions & 6 deletions c2rust-analyze/src/rewrite/expr/mir_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ pub enum RewriteKind {
src_single: bool,
dest_single: bool,
},
CallocSafe {
zero_ty: ZeroizeType,
elem_size: u64,
single: bool,
},

/// Convert `Option<T>` to `T` by calling `.unwrap()`.
OptionUnwrap,
Expand Down Expand Up @@ -641,7 +646,7 @@ impl<'a, 'tcx> ExprRewriteVisitor<'a, 'tcx> {
});
}

Callee::Malloc => {
ref callee @ (Callee::Malloc | Callee::Calloc) => {
self.enter_rvalue(|v| {
let dest_lty = v.acx.type_of(destination);
let dest_pointee = v.pointee_lty(dest_lty);
Expand All @@ -667,11 +672,20 @@ impl<'a, 'tcx> ExprRewriteVisitor<'a, 'tcx> {
None => return,
};

v.emit(RewriteKind::MallocSafe {
zero_ty,
elem_size,
single,
});
let rw = match *callee {
Callee::Malloc => RewriteKind::MallocSafe {
zero_ty,
elem_size,
single,
},
Callee::Calloc => RewriteKind::CallocSafe {
zero_ty,
elem_size,
single,
},
_ => unreachable!(),
};
v.emit(rw);

// `MallocSafe` produces either `Box<T>` or `Box<[T]>`. Emit a cast
// from that type to the required output type.
Expand Down

0 comments on commit 6a091e1

Please sign in to comment.