Skip to content

Commit 3dd70a8

Browse files
committed
transpile: Avoid some identity transmutes for function pointers
1 parent eaa6c3c commit 3dd70a8

File tree

2 files changed

+36
-22
lines changed

2 files changed

+36
-22
lines changed

c2rust-transpile/src/translator/mod.rs

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3495,12 +3495,14 @@ impl<'c> Translation<'c> {
34953495
parameters,
34963496
)?;
34973497
if let Some(actual_ty) = actual_ty {
3498-
// If we're casting a concrete function to
3499-
// a K&R function pointer type, use transmute
3500-
self.import_type(qual_ty.ctype);
3498+
if actual_ty != ty {
3499+
// If we're casting a concrete function to
3500+
// a K&R function pointer type, use transmute
3501+
self.import_type(qual_ty.ctype);
35013502

3502-
val = transmute_expr(actual_ty, ty, val);
3503-
set_unsafe = true;
3503+
val = transmute_expr(actual_ty, ty, val);
3504+
set_unsafe = true;
3505+
}
35043506
} else {
35053507
let decl_kind = &self.ast_context[decl_id].kind;
35063508
let kind_with_declared_args =
@@ -4406,21 +4408,35 @@ impl<'c> Translation<'c> {
44064408

44074409
match kind {
44084410
CastKind::BitCast | CastKind::NoOp => {
4409-
val.and_then(|x| {
4410-
if self.ast_context.is_function_pointer(target_cty.ctype)
4411-
|| self.ast_context.is_function_pointer(source_cty.ctype)
4412-
{
4413-
let source_ty = self.convert_type(source_cty.ctype)?;
4414-
let target_ty = self.convert_type(target_cty.ctype)?;
4411+
if self.ast_context.is_function_pointer(target_cty.ctype)
4412+
|| self.ast_context.is_function_pointer(source_cty.ctype)
4413+
{
4414+
let source_ty = self
4415+
.type_converter
4416+
.borrow_mut()
4417+
.convert(&self.ast_context, source_cty.ctype)?;
4418+
let target_ty = self
4419+
.type_converter
4420+
.borrow_mut()
4421+
.convert(&self.ast_context, target_cty.ctype)?;
4422+
4423+
if source_ty == target_ty {
4424+
return Ok(val);
4425+
}
4426+
4427+
self.import_type(source_cty.ctype);
4428+
self.import_type(target_cty.ctype);
4429+
4430+
val.and_then(|val| {
44154431
Ok(WithStmts::new_unsafe_val(transmute_expr(
4416-
source_ty, target_ty, x,
4432+
source_ty, target_ty, val,
44174433
)))
4418-
} else {
4419-
// Normal case
4420-
let target_ty = self.convert_type(target_cty.ctype)?;
4421-
Ok(WithStmts::new_val(mk().cast_expr(x, target_ty)))
4422-
}
4423-
})
4434+
})
4435+
} else {
4436+
// Normal case
4437+
let target_ty = self.convert_type(target_cty.ctype)?;
4438+
Ok(val.map(|val| mk().cast_expr(val, target_ty)))
4439+
}
44244440
}
44254441

44264442
CastKind::IntegralToPointer

c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.snap

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,8 @@ pub unsafe extern "C" fn unary_with_side_effect() {
4444
side_effect();
4545
!side_effect();
4646
(side_effect() == 0) as ::core::ffi::c_int;
47-
(b"\0" as *const u8 as *const ::core::ffi::c_char).offset(::core::mem::transmute::<
48-
unsafe extern "C" fn() -> ::core::ffi::c_int,
49-
unsafe extern "C" fn() -> ::core::ffi::c_int,
50-
>(side_effect)() as isize) as *const ::core::ffi::c_char;
47+
(b"\0" as *const u8 as *const ::core::ffi::c_char).offset(side_effect() as isize)
48+
as *const ::core::ffi::c_char;
5149
*arr[side_effect() as usize];
5250
arr[side_effect() as usize] = arr[side_effect() as usize].offset(1);
5351
arr[side_effect() as usize] = arr[side_effect() as usize].offset(-1);

0 commit comments

Comments
 (0)