From fd2f8f5bce44c2403eed56bfe589c59af10a514f Mon Sep 17 00:00:00 2001 From: Rua Date: Tue, 9 Jun 2026 18:18:42 +0200 Subject: [PATCH 01/12] transpile: Use `make_cast` when casting to expected type --- c2rust-transpile/src/translator/functions.rs | 17 +++---- c2rust-transpile/src/translator/mod.rs | 49 ++++++++++--------- c2rust-transpile/src/translator/pointers.rs | 15 +++--- .../src/translator/structs_unions.rs | 8 +-- ...s__transpile@auto_type.c.2021.clang22.snap | 2 +- ...s__transpile@auto_type.c.2024.clang22.snap | 2 +- ...__transpile@f128.c.2021.macos.clang15.snap | 8 +-- ...__transpile@f128.c.2024.macos.clang15.snap | 8 +-- ...hots__transpile@macros.c.2021.clang15.snap | 2 +- ...transpile@macros.c.2021.linux.clang15.snap | 6 +-- ...transpile@macros.c.2021.macos.clang15.snap | 6 +-- ...hots__transpile@macros.c.2024.clang15.snap | 2 +- ...transpile@macros.c.2024.linux.clang15.snap | 6 +-- ...transpile@macros.c.2024.macos.clang15.snap | 6 +-- ...ile@wide_strings.c.2021.linux.clang22.snap | 2 +- ...ile@wide_strings.c.2021.macos.clang22.snap | 2 +- ...ile@wide_strings.c.2024.linux.clang22.snap | 2 +- ...ile@wide_strings.c.2024.macos.clang22.snap | 2 +- 18 files changed, 72 insertions(+), 73 deletions(-) diff --git a/c2rust-transpile/src/translator/functions.rs b/c2rust-transpile/src/translator/functions.rs index bedff5e479..5f0795c405 100644 --- a/c2rust-transpile/src/translator/functions.rs +++ b/c2rust-transpile/src/translator/functions.rs @@ -452,16 +452,13 @@ impl<'c> Translation<'c> { let args = self.convert_call_args(ctx.used(), args, arg_tys.as_deref(), is_variadic)?; - let mut call_expr = args.map(|args| mk().call_expr(func, args)); - if let Some(expected_ty) = override_ty { - if call_expr_ty != expected_ty { - let ret_ty = self.convert_type(expected_ty.ctype)?; - call_expr = call_expr.map(|call| mk().cast_expr(call, ret_ty)); - } - } - - let res: TranslationResult<_> = Ok(call_expr); - res + let call_expr = args.map(|args| mk().call_expr(func, args)); + self.make_cast( + ctx, + call_expr_ty, + override_ty.unwrap_or(call_expr_ty), + call_expr, + ) })?; self.convert_side_effects_expr( diff --git a/c2rust-transpile/src/translator/mod.rs b/c2rust-transpile/src/translator/mod.rs index f03409c5ed..d4d9a5247d 100644 --- a/c2rust-transpile/src/translator/mod.rs +++ b/c2rust-transpile/src/translator/mod.rs @@ -2870,15 +2870,16 @@ impl<'c> Translation<'c> { pub fn compute_size_of_type( &self, ctx: ExprContext, + expected_type_id: Option, + result_type_id: CQualTypeId, type_id: CTypeId, - override_ty: Option, ) -> TranslationResult>> { if let CTypeKind::VariableArray(elts, len) = self.ast_context.resolve_type(type_id).kind { let len = len.expect("Sizeof a VLA type with count expression omitted"); - let elts = self.compute_size_of_type(ctx, elts, override_ty)?; + let elts = self.compute_size_of_type(ctx, expected_type_id, result_type_id, elts)?; return elts.and_then_try(|lhs| { - let len = self.convert_expr(ctx.used().not_static(), len, override_ty)?; + let len = self.convert_expr(ctx.used().not_static(), len, expected_type_id)?; Ok(len.map(|len| { let rhs = cast_int(len, "usize", true); mk().binary_expr(BinOp::Mul(Default::default()), lhs, rhs) @@ -2886,17 +2887,14 @@ impl<'c> Translation<'c> { }); } let ty = self.convert_type(type_id)?; - let mut result = self.mk_size_of_ty_expr(ty); - // cast to expected ty if one is known - if let Some(expected_ty) = override_ty { - trace!( - "Converting result of sizeof to {:?}", - self.ast_context.resolve_type(expected_ty.ctype) - ); - let result_ty = self.convert_type(expected_ty.ctype)?; - result = result.map(|x| x.map(|x| mk().cast_expr(x, result_ty))); - } - result + let result = self.mk_size_of_ty_expr(ty)?; + + self.make_cast( + ctx, + result_type_id, + expected_type_id.unwrap_or(result_type_id), + result, + ) } fn mk_size_of_ty_expr(&self, ty: Box) -> TranslationResult>> { @@ -3031,13 +3029,19 @@ impl<'c> Translation<'c> { }), ConvertVector(..) => Err(TranslationError::generic("convert vector not supported")), - UnaryType(_ty, kind, opt_expr, arg_ty) => { + UnaryType(result_type_id, kind, opt_expr, arg_ty) => { let result = match kind { CUnTypeOp::SizeOf => match opt_expr { - None => self.compute_size_of_type(ctx, arg_ty.ctype, override_ty)?, + None => self.compute_size_of_type( + ctx, + override_ty, + result_type_id, + arg_ty.ctype, + )?, Some(_) => { let inner = self.variable_array_base_type(arg_ty.ctype); - let inner_size = self.compute_size_of_type(ctx, inner, override_ty)?; + let inner_size = + self.compute_size_of_type(ctx, override_ty, result_type_id, inner)?; if let Some(sz) = self.compute_size_of_expr(arg_ty.ctype) { inner_size.map(|x| { @@ -3188,14 +3192,13 @@ impl<'c> Translation<'c> { val = mk().method_call_expr(val, "as_mut_ptr", vec![]); } - // if the context wants a different type, add a cast - if let Some(expected_ty) = override_ty { - if lrvalue.is_rvalue() && expected_ty != qual_ty { - val = mk().cast_expr(val, self.convert_type(expected_ty.ctype)?); - } + let mut val = WithStmts::new_val(val).merge_unsafe(set_unsafe); + + if lrvalue.is_rvalue() { + val = self.make_cast(ctx, qual_ty, override_ty.unwrap_or(qual_ty), val)?; } - Ok(WithStmts::new_val(val).merge_unsafe(set_unsafe)) + Ok(val) } OffsetOf(ty, ref kind) => match kind { diff --git a/c2rust-transpile/src/translator/pointers.rs b/c2rust-transpile/src/translator/pointers.rs index 5428ce9e6b..706b8043d0 100644 --- a/c2rust-transpile/src/translator/pointers.rs +++ b/c2rust-transpile/src/translator/pointers.rs @@ -342,13 +342,16 @@ impl<'c> Translation<'c> { let mut val = self.convert_pointer_offset(lhs, rhs, pointee_type_id.ctype, false, deref); - // if the context wants a different type, add a cast - if let Some(expected_ty) = override_ty { - if lrvalue.is_rvalue() && expected_ty != pointee_type_id { - let ty = self.convert_type(expected_ty.ctype)?; - val = val.map(|val| mk().cast_expr(val, ty)); - } + + if lrvalue.is_rvalue() { + val = self.make_cast( + ctx, + pointee_type_id, + override_ty.unwrap_or(pointee_type_id), + val, + )?; } + Ok(val) }) } diff --git a/c2rust-transpile/src/translator/structs_unions.rs b/c2rust-transpile/src/translator/structs_unions.rs index a14821c472..cbe27cfc72 100644 --- a/c2rust-transpile/src/translator/structs_unions.rs +++ b/c2rust-transpile/src/translator/structs_unions.rs @@ -1043,12 +1043,8 @@ impl<'a> Translation<'a> { val = val.map(|v| mk().field_expr(v, field_name)); }; - // if the context wants a different type, add a cast - if let Some(expected_ty) = override_ty { - if lrvalue.is_rvalue() && expected_ty != qual_ty { - let ty = self.convert_type(expected_ty.ctype)?; - val = val.map(|v| mk().cast_expr(v, ty)); - } + if lrvalue.is_rvalue() { + val = self.make_cast(ctx, qual_ty, override_ty.unwrap_or(qual_ty), val)?; } Ok(val) diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@auto_type.c.2021.clang22.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@auto_type.c.2021.clang22.snap index 4f70a5e0d6..1cf710a387 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@auto_type.c.2021.clang22.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@auto_type.c.2021.clang22.snap @@ -21,7 +21,7 @@ pub struct bar { pub unsafe extern "C" fn foo() -> ::core::ffi::c_int { let mut x: ::core::ffi::c_int = 42 as ::core::ffi::c_int; let mut px: *mut ::core::ffi::c_int = &raw mut x; - let mut sx: usize = ::core::mem::size_of::<::core::ffi::c_int>() as usize; + let mut sx: usize = ::core::mem::size_of::<::core::ffi::c_int>(); let mut y: bar = bar { x: x as ::core::ffi::c_int, } as bar; diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@auto_type.c.2024.clang22.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@auto_type.c.2024.clang22.snap index 54d6600fc3..4118c1258c 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@auto_type.c.2024.clang22.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@auto_type.c.2024.clang22.snap @@ -21,7 +21,7 @@ pub struct bar { pub unsafe extern "C" fn foo() -> ::core::ffi::c_int { let mut x: ::core::ffi::c_int = 42 as ::core::ffi::c_int; let mut px: *mut ::core::ffi::c_int = &raw mut x; - let mut sx: usize = ::core::mem::size_of::<::core::ffi::c_int>() as usize; + let mut sx: usize = ::core::mem::size_of::<::core::ffi::c_int>(); let mut y: bar = bar { x: x as ::core::ffi::c_int, } as bar; diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@f128.c.2021.macos.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@f128.c.2021.macos.clang15.snap index 071c9c898d..937d379b39 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@f128.c.2021.macos.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@f128.c.2021.macos.clang15.snap @@ -34,12 +34,12 @@ pub unsafe extern "C" fn long_double_test() { let mut f: ::core::ffi::c_float = one.to_f32().unwrap(); let mut cast_from_int: ::f128::f128 = ::f128::f128::new(i); let mut cast_from_float: ::f128::f128 = ::f128::f128::new(f); - let mut is_inf: bool = if ::core::mem::size_of::<::f128::f128>() as usize - == ::core::mem::size_of::<::core::ffi::c_float>() as usize + let mut is_inf: bool = if ::core::mem::size_of::<::f128::f128>() + == ::core::mem::size_of::<::core::ffi::c_float>() { __inline_isinff(huge.to_f32().unwrap()) - } else if ::core::mem::size_of::<::f128::f128>() as usize - == ::core::mem::size_of::<::core::ffi::c_double>() as usize + } else if ::core::mem::size_of::<::f128::f128>() + == ::core::mem::size_of::<::core::ffi::c_double>() { __inline_isinfd(huge.to_f64().unwrap()) } else { diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@f128.c.2024.macos.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@f128.c.2024.macos.clang15.snap index 5444375917..4bc1bece15 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@f128.c.2024.macos.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@f128.c.2024.macos.clang15.snap @@ -35,12 +35,12 @@ pub unsafe extern "C" fn long_double_test() { let mut f: ::core::ffi::c_float = one.to_f32().unwrap(); let mut cast_from_int: ::f128::f128 = ::f128::f128::new(i); let mut cast_from_float: ::f128::f128 = ::f128::f128::new(f); - let mut is_inf: bool = if ::core::mem::size_of::<::f128::f128>() as usize - == ::core::mem::size_of::<::core::ffi::c_float>() as usize + let mut is_inf: bool = if ::core::mem::size_of::<::f128::f128>() + == ::core::mem::size_of::<::core::ffi::c_float>() { __inline_isinff(huge.to_f32().unwrap()) - } else if ::core::mem::size_of::<::f128::f128>() as usize - == ::core::mem::size_of::<::core::ffi::c_double>() as usize + } else if ::core::mem::size_of::<::f128::f128>() + == ::core::mem::size_of::<::core::ffi::c_double>() { __inline_isinfd(huge.to_f64().unwrap()) } else { diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap index b059b1a47f..4a6bf74a66 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.clang15.snap @@ -348,7 +348,7 @@ pub static mut p: *const fn_ptrs = unsafe { &raw const fns }; pub const ZSTD_WINDOWLOG_MAX_32: ::core::ffi::c_int = 30 as ::core::ffi::c_int; pub const ZSTD_WINDOWLOG_MAX_64: ::core::ffi::c_int = 31 as ::core::ffi::c_int; pub const ZSTD_WINDOWLOG_MAX: ::core::ffi::c_int = - if ::core::mem::size_of::() as usize == 4 as usize { + if ::core::mem::size_of::() == 4 as usize { ZSTD_WINDOWLOG_MAX_32 } else { ZSTD_WINDOWLOG_MAX_64 diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.linux.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.linux.clang15.snap index 80c821caba..61e3ab6dc8 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.linux.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.linux.clang15.snap @@ -37,10 +37,10 @@ pub unsafe extern "C" fn memcpy_str_literal(mut out: *mut ::core::ffi::c_char) { memcpy( out as *mut ::core::ffi::c_void, POS.as_ptr() as *const ::core::ffi::c_void, - (::core::mem::size_of::<[::core::ffi::c_char; 3]>() as size_t) - .wrapping_div(::core::mem::size_of::<::core::ffi::c_char>() as size_t) + ::core::mem::size_of::<[::core::ffi::c_char; 3]>() + .wrapping_div(::core::mem::size_of::<::core::ffi::c_char>()) .wrapping_sub(1 as size_t) .wrapping_add(1 as size_t) - .wrapping_mul(::core::mem::size_of::<::core::ffi::c_char>() as size_t), + .wrapping_mul(::core::mem::size_of::<::core::ffi::c_char>()), ); } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.macos.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.macos.clang15.snap index c62e4c3575..332dbf22d5 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.macos.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2021.macos.clang15.snap @@ -37,10 +37,10 @@ pub unsafe extern "C" fn memcpy_str_literal(mut out: *mut ::core::ffi::c_char) { memcpy( out as *mut ::core::ffi::c_void, POS.as_ptr() as *const ::core::ffi::c_void, - (::core::mem::size_of::<[::core::ffi::c_char; 3]>() as size_t) - .wrapping_div(::core::mem::size_of::<::core::ffi::c_char>() as size_t) + ::core::mem::size_of::<[::core::ffi::c_char; 3]>() + .wrapping_div(::core::mem::size_of::<::core::ffi::c_char>()) .wrapping_sub(1 as size_t) .wrapping_add(1 as size_t) - .wrapping_mul(::core::mem::size_of::<::core::ffi::c_char>() as size_t), + .wrapping_mul(::core::mem::size_of::<::core::ffi::c_char>()), ); } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.clang15.snap index 1541727a10..2371213a97 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.clang15.snap @@ -348,7 +348,7 @@ pub static mut p: *const fn_ptrs = &raw const fns; pub const ZSTD_WINDOWLOG_MAX_32: ::core::ffi::c_int = 30 as ::core::ffi::c_int; pub const ZSTD_WINDOWLOG_MAX_64: ::core::ffi::c_int = 31 as ::core::ffi::c_int; pub const ZSTD_WINDOWLOG_MAX: ::core::ffi::c_int = - if ::core::mem::size_of::() as usize == 4 as usize { + if ::core::mem::size_of::() == 4 as usize { ZSTD_WINDOWLOG_MAX_32 } else { ZSTD_WINDOWLOG_MAX_64 diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.linux.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.linux.clang15.snap index 9c0e25280c..5f4f4e2e3a 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.linux.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.linux.clang15.snap @@ -38,10 +38,10 @@ pub unsafe extern "C" fn memcpy_str_literal(mut out: *mut ::core::ffi::c_char) { memcpy( out as *mut ::core::ffi::c_void, POS.as_ptr() as *const ::core::ffi::c_void, - (::core::mem::size_of::<[::core::ffi::c_char; 3]>() as size_t) - .wrapping_div(::core::mem::size_of::<::core::ffi::c_char>() as size_t) + ::core::mem::size_of::<[::core::ffi::c_char; 3]>() + .wrapping_div(::core::mem::size_of::<::core::ffi::c_char>()) .wrapping_sub(1 as size_t) .wrapping_add(1 as size_t) - .wrapping_mul(::core::mem::size_of::<::core::ffi::c_char>() as size_t), + .wrapping_mul(::core::mem::size_of::<::core::ffi::c_char>()), ); } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.macos.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.macos.clang15.snap index 67bc9dff79..b12cf95c82 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.macos.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@macros.c.2024.macos.clang15.snap @@ -38,10 +38,10 @@ pub unsafe extern "C" fn memcpy_str_literal(mut out: *mut ::core::ffi::c_char) { memcpy( out as *mut ::core::ffi::c_void, POS.as_ptr() as *const ::core::ffi::c_void, - (::core::mem::size_of::<[::core::ffi::c_char; 3]>() as size_t) - .wrapping_div(::core::mem::size_of::<::core::ffi::c_char>() as size_t) + ::core::mem::size_of::<[::core::ffi::c_char; 3]>() + .wrapping_div(::core::mem::size_of::<::core::ffi::c_char>()) .wrapping_sub(1 as size_t) .wrapping_add(1 as size_t) - .wrapping_mul(::core::mem::size_of::<::core::ffi::c_char>() as size_t), + .wrapping_mul(::core::mem::size_of::<::core::ffi::c_char>()), ); } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2021.linux.clang22.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2021.linux.clang22.snap index 056da46626..22123a283c 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2021.linux.clang22.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2021.linux.clang22.snap @@ -42,5 +42,5 @@ pub unsafe extern "C" fn func() { let mut ptr: *const wchar_t = const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") } .as_ptr() as *const wchar_t; - let mut len: size_t = wcslen(&raw mut array as *mut wchar_t) as size_t; + let mut len: size_t = wcslen(&raw mut array as *mut wchar_t); } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2021.macos.clang22.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2021.macos.clang22.snap index 0948979cd3..a0000c4f2b 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2021.macos.clang22.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2021.macos.clang22.snap @@ -42,5 +42,5 @@ pub unsafe extern "C" fn func() { let mut ptr: *const wchar_t = const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") } .as_ptr() as *const wchar_t; - let mut len: size_t = wcslen(&raw mut array as *mut wchar_t) as size_t; + let mut len: size_t = wcslen(&raw mut array as *mut wchar_t); } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2024.linux.clang22.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2024.linux.clang22.snap index eb9d4a3513..8b4454e10e 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2024.linux.clang22.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2024.linux.clang22.snap @@ -42,5 +42,5 @@ pub unsafe extern "C" fn func() { let mut ptr: *const wchar_t = const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") } .as_ptr() as *const wchar_t; - let mut len: size_t = wcslen(&raw mut array as *mut wchar_t) as size_t; + let mut len: size_t = wcslen(&raw mut array as *mut wchar_t); } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2024.macos.clang22.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2024.macos.clang22.snap index 51a9510f93..f9c7aa4934 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2024.macos.clang22.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2024.macos.clang22.snap @@ -42,5 +42,5 @@ pub unsafe extern "C" fn func() { let mut ptr: *const wchar_t = const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") } .as_ptr() as *const wchar_t; - let mut len: size_t = wcslen(&raw mut array as *mut wchar_t) as size_t; + let mut len: size_t = wcslen(&raw mut array as *mut wchar_t); } From 107cf399fc482bac3526b75f206efb55e7dfedda Mon Sep 17 00:00:00 2001 From: Rua Date: Tue, 9 Jun 2026 18:21:22 +0200 Subject: [PATCH 02/12] transpile: Pass expected type for `AlignOf` and `PreferredAlignOf` --- c2rust-transpile/src/translator/mod.rs | 32 ++++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/c2rust-transpile/src/translator/mod.rs b/c2rust-transpile/src/translator/mod.rs index d4d9a5247d..fdddfb010b 100644 --- a/c2rust-transpile/src/translator/mod.rs +++ b/c2rust-transpile/src/translator/mod.rs @@ -2912,6 +2912,9 @@ impl<'c> Translation<'c> { pub fn compute_align_of_type( &self, + ctx: ExprContext, + expected_type_id: Option, + result_type_id: CQualTypeId, mut type_id: CTypeId, preferred: bool, src_loc: &Option, @@ -2948,7 +2951,12 @@ impl<'c> Translation<'c> { path.push(mk().path_segment_with_args("align_of", mk().angle_bracketed_args(tys))); } let call = mk().call_expr(mk().abs_path_expr(path), vec![]); - Ok(WithStmts::new_val(call)) + self.make_cast( + ctx, + result_type_id, + expected_type_id.unwrap_or(result_type_id), + WithStmts::new_val(call), + ) } /// Convert multiple expressions (while collecting a context of statements) given either all or @@ -3053,12 +3061,22 @@ impl<'c> Translation<'c> { } } }, - CUnTypeOp::AlignOf => { - self.compute_align_of_type(arg_ty.ctype, false, src_loc)? - } - CUnTypeOp::PreferredAlignOf => { - self.compute_align_of_type(arg_ty.ctype, true, src_loc)? - } + CUnTypeOp::AlignOf => self.compute_align_of_type( + ctx, + override_ty, + result_type_id, + arg_ty.ctype, + false, + src_loc, + )?, + CUnTypeOp::PreferredAlignOf => self.compute_align_of_type( + ctx, + override_ty, + result_type_id, + arg_ty.ctype, + true, + src_loc, + )?, }; Ok(result) From 87a822fd0510d8b41fc1069ad1d3b67045e25d33 Mon Sep 17 00:00:00 2001 From: Rua Date: Tue, 9 Jun 2026 18:27:52 +0200 Subject: [PATCH 03/12] transpile: Pass expected type for `ImplicitValueInit` --- c2rust-transpile/src/translator/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/c2rust-transpile/src/translator/mod.rs b/c2rust-transpile/src/translator/mod.rs index fdddfb010b..f9b822a268 100644 --- a/c2rust-transpile/src/translator/mod.rs +++ b/c2rust-transpile/src/translator/mod.rs @@ -3412,7 +3412,9 @@ impl<'c> Translation<'c> { self.convert_init_list(ctx, override_ty, ty, ids, opt_union_field_id) } - ImplicitValueInit(ty) => self.implicit_default_expr(ctx, ty.ctype), + ImplicitValueInit(ty) => { + self.implicit_default_expr(ctx, override_ty.unwrap_or(ty).ctype) + } Predefined(_, val_id) => self.convert_expr(ctx, val_id, override_ty), From 95abab1f35b0d4bf9201a99a5c7650b32c0a60dc Mon Sep 17 00:00:00 2001 From: Rua Date: Wed, 10 Jun 2026 19:44:53 +0200 Subject: [PATCH 04/12] transpile: Pass expected type for `ConstantExpr` --- c2rust-transpile/src/translator/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c2rust-transpile/src/translator/mod.rs b/c2rust-transpile/src/translator/mod.rs index f9b822a268..32acdf5b83 100644 --- a/c2rust-transpile/src/translator/mod.rs +++ b/c2rust-transpile/src/translator/mod.rs @@ -3086,7 +3086,7 @@ impl<'c> Translation<'c> { if let Some(constant) = value { self.convert_constant(constant).map(WithStmts::new_val) } else { - self.convert_expr(ctx, child, Some(ty)) + self.convert_expr(ctx, child, Some(override_ty.unwrap_or(ty))) } } From ad3c0387a5032deb2ec480ba74741e94d9d9ae91 Mon Sep 17 00:00:00 2001 From: Rua Date: Fri, 15 May 2026 15:12:55 +0200 Subject: [PATCH 05/12] transpile: Use more descriptive name for fresh lvalue variable --- c2rust-transpile/src/translator/named_references.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c2rust-transpile/src/translator/named_references.rs b/c2rust-transpile/src/translator/named_references.rs index 640fb42be1..03fbec5fac 100644 --- a/c2rust-transpile/src/translator/named_references.rs +++ b/c2rust-transpile/src/translator/named_references.rs @@ -122,7 +122,7 @@ impl<'c> Translation<'c> { } else { // This is the case where we explicitly need to factor out possible side-effects. - let ptr_name = self.renamer.borrow_mut().fresh(); + let ptr_name = self.renamer.borrow_mut().pick_name("c2rust_lvalue_ptr"); // let ref mut p = lhs; let compute_ref = mk().local_stmt(Box::new(mk().local( From a888e71f1c69742c4af429de7d9422031dc9bc64 Mon Sep 17 00:00:00 2001 From: Rua Date: Sat, 2 May 2026 11:28:08 +0200 Subject: [PATCH 06/12] transpile: Rename unused `if_else` snapshot test and activate it --- c2rust-transpile/tests/snapshots.rs | 5 + .../snapshots/{if_else.c => conditions.c} | 0 ..._transpile@conditions.c.2021.clang15.snap} | 3 +- ...__transpile@conditions.c.2024.clang15.snap | 95 +++++++++++++++++++ 4 files changed, 101 insertions(+), 2 deletions(-) rename c2rust-transpile/tests/snapshots/{if_else.c => conditions.c} (100%) rename c2rust-transpile/tests/snapshots/{snapshots__transpile@if_else.c.snap => snapshots__transpile@conditions.c.2021.clang15.snap} (96%) create mode 100644 c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2024.clang15.snap diff --git a/c2rust-transpile/tests/snapshots.rs b/c2rust-transpile/tests/snapshots.rs index df95f3719f..4b79e8e96f 100644 --- a/c2rust-transpile/tests/snapshots.rs +++ b/c2rust-transpile/tests/snapshots.rs @@ -354,6 +354,11 @@ fn test_compound_literals() { transpile("compound_literals.c").run(); } +#[test] +fn test_conditions() { + transpile("conditions.c").run(); +} + #[test] fn test_const_macro_bitfield() { transpile("const_macro_bitfield.c") diff --git a/c2rust-transpile/tests/snapshots/if_else.c b/c2rust-transpile/tests/snapshots/conditions.c similarity index 100% rename from c2rust-transpile/tests/snapshots/if_else.c rename to c2rust-transpile/tests/snapshots/conditions.c diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@if_else.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2021.clang15.snap similarity index 96% rename from c2rust-transpile/tests/snapshots/snapshots__transpile@if_else.c.snap rename to c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2021.clang15.snap index 05f99290ee..dfc0b11d92 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@if_else.c.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2021.clang15.snap @@ -1,7 +1,6 @@ --- source: c2rust-transpile/tests/snapshots.rs -expression: cat tests/snapshots/if_else.rs -input_file: c2rust-transpile/tests/snapshots/if_else.c +expression: cat tests/snapshots/conditions.2021.clang15.rs --- #![allow( clippy::missing_safety_doc, diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2024.clang15.snap new file mode 100644 index 0000000000..66ae3f2987 --- /dev/null +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2024.clang15.snap @@ -0,0 +1,95 @@ +--- +source: c2rust-transpile/tests/snapshots.rs +expression: cat tests/snapshots/conditions.2024.clang15.rs +--- +#![allow( + clippy::missing_safety_doc, + dead_code, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unsafe_op_in_unsafe_fn, + unused_assignments, + unused_mut +)] +#[unsafe(no_mangle)] +pub unsafe extern "C" fn simple_if_else(mut x: ::core::ffi::c_int) -> ::core::ffi::c_int { + if x != 0 { + x += 1 as ::core::ffi::c_int; + } else { + x += 2 as ::core::ffi::c_int; + } + return x; +} +#[unsafe(no_mangle)] +pub unsafe extern "C" fn if_no_else(mut x: ::core::ffi::c_int) -> ::core::ffi::c_int { + if x > 0 as ::core::ffi::c_int { + x += 1 as ::core::ffi::c_int; + } + return x; +} +#[unsafe(no_mangle)] +pub unsafe extern "C" fn multiple_ifs(mut x: ::core::ffi::c_int) -> ::core::ffi::c_int { + if x != 0 { + x += 1 as ::core::ffi::c_int; + } + if x != 0 { + x += 2 as ::core::ffi::c_int; + } + return x; +} +#[unsafe(no_mangle)] +pub unsafe extern "C" fn nested_if_else(mut x: ::core::ffi::c_int) -> ::core::ffi::c_int { + if x > 0 as ::core::ffi::c_int { + if x < 10 as ::core::ffi::c_int { + x += 1 as ::core::ffi::c_int; + } else { + x += 2 as ::core::ffi::c_int; + } + } else { + x -= 1 as ::core::ffi::c_int; + } + return x; +} +#[unsafe(no_mangle)] +pub unsafe extern "C" fn nested_if_no_else(mut x: ::core::ffi::c_int) -> ::core::ffi::c_int { + if x > 0 as ::core::ffi::c_int { + if x < 10 as ::core::ffi::c_int { + x += 1 as ::core::ffi::c_int; + } + x += 2 as ::core::ffi::c_int; + } else { + x -= 1 as ::core::ffi::c_int; + } + return x; +} +#[unsafe(no_mangle)] +pub unsafe extern "C" fn early_returns(mut a: ::core::ffi::c_int) -> ::core::ffi::c_int { + if a == 2 as ::core::ffi::c_int { + return 2 as ::core::ffi::c_int; + } + if a == 3 as ::core::ffi::c_int { + a += 1 as ::core::ffi::c_int; + } + if a == 4 as ::core::ffi::c_int { + return 1 as ::core::ffi::c_int; + } + return 0 as ::core::ffi::c_int; +} +#[unsafe(no_mangle)] +pub unsafe extern "C" fn nested_early_returns(mut x: ::core::ffi::c_int) -> ::core::ffi::c_int { + if x != 0 { + if x != 0 { + x += 1 as ::core::ffi::c_int; + return x; + } + x += 2 as ::core::ffi::c_int; + } else { + if x != 0 { + x += 3 as ::core::ffi::c_int; + return x; + } + x += 4 as ::core::ffi::c_int; + } + return x; +} From f219baa16f0b9085bb95ebbd1e4dfed26f7c327b Mon Sep 17 00:00:00 2001 From: Rua Date: Sat, 2 May 2026 11:33:12 +0200 Subject: [PATCH 07/12] transpile: Add conditional operators to `conditions.c` snapshot test --- c2rust-transpile/tests/snapshots/conditions.c | 19 +++++ ...__transpile@conditions.c.2021.clang15.snap | 75 +++++++++++++++++++ ...__transpile@conditions.c.2024.clang15.snap | 74 ++++++++++++++++++ 3 files changed, 168 insertions(+) diff --git a/c2rust-transpile/tests/snapshots/conditions.c b/c2rust-transpile/tests/snapshots/conditions.c index 0c14291440..9eb0da5ebc 100644 --- a/c2rust-transpile/tests/snapshots/conditions.c +++ b/c2rust-transpile/tests/snapshots/conditions.c @@ -83,3 +83,22 @@ int nested_early_returns(int x) { } return x; } + +void conditional_operator(const unsigned sz, int buf[const]) { + int x = 0, y = 1; + *(0 ? &y : &x) = 10; + + buf[2] = 1 ? 2 : 3; + buf[3] = 0 ? 2 : 3; +} + +static int id(int i) { return i;} +static int add(int *p, int i, int r) { *p += i; return r;} + +void binary_conditional_operator(const unsigned sz, int buf[const]) { + buf[0] = id(0) ?: id(1); + buf[1] = id(2) ?: id(3); + + (void) (add(buf+2, 2, 0) ?: add(buf+3, 3, 0)); + (void) (add(buf+4, 4, 1) ?: add(buf+5, 5, 0)); +} diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2021.clang15.snap index dfc0b11d92..70446a3d2e 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2021.clang15.snap @@ -11,6 +11,7 @@ expression: cat tests/snapshots/conditions.2021.clang15.rs unused_assignments, unused_mut )] +#![feature(raw_ref_op)] #[no_mangle] pub unsafe extern "C" fn simple_if_else(mut x: ::core::ffi::c_int) -> ::core::ffi::c_int { if x != 0 { @@ -92,3 +93,77 @@ pub unsafe extern "C" fn nested_early_returns(mut x: ::core::ffi::c_int) -> ::co } return x; } +#[no_mangle] +pub unsafe extern "C" fn conditional_operator( + sz: ::core::ffi::c_uint, + buf: *mut ::core::ffi::c_int, +) { + let mut x: ::core::ffi::c_int = 0 as ::core::ffi::c_int; + let mut y: ::core::ffi::c_int = 1 as ::core::ffi::c_int; + *if false { &raw mut y } else { &raw mut x } = 10 as ::core::ffi::c_int; + *(buf as *mut ::core::ffi::c_int).offset(2 as ::core::ffi::c_int as isize) = if true { + 2 as ::core::ffi::c_int + } else { + 3 as ::core::ffi::c_int + }; + *(buf as *mut ::core::ffi::c_int).offset(3 as ::core::ffi::c_int as isize) = if false { + 2 as ::core::ffi::c_int + } else { + 3 as ::core::ffi::c_int + }; +} +unsafe extern "C" fn id(mut i: ::core::ffi::c_int) -> ::core::ffi::c_int { + return i; +} +unsafe extern "C" fn add( + mut p: *mut ::core::ffi::c_int, + mut i: ::core::ffi::c_int, + mut r: ::core::ffi::c_int, +) -> ::core::ffi::c_int { + *p += i; + return r; +} +#[no_mangle] +pub unsafe extern "C" fn binary_conditional_operator( + sz: ::core::ffi::c_uint, + buf: *mut ::core::ffi::c_int, +) { + let ref mut c2rust_lvalue_ptr = id(0 as ::core::ffi::c_int); + *(buf as *mut ::core::ffi::c_int).offset(0 as ::core::ffi::c_int as isize) = + if *c2rust_lvalue_ptr != 0 { + *c2rust_lvalue_ptr + } else { + id(1 as ::core::ffi::c_int) + }; + let ref mut c2rust_lvalue_ptr_0 = id(2 as ::core::ffi::c_int); + *(buf as *mut ::core::ffi::c_int).offset(1 as ::core::ffi::c_int as isize) = + if *c2rust_lvalue_ptr_0 != 0 { + *c2rust_lvalue_ptr_0 + } else { + id(3 as ::core::ffi::c_int) + }; + if add( + (buf as *mut ::core::ffi::c_int).offset(2 as ::core::ffi::c_int as isize), + 2 as ::core::ffi::c_int, + 0 as ::core::ffi::c_int, + ) == 0 + { + add( + (buf as *mut ::core::ffi::c_int).offset(3 as ::core::ffi::c_int as isize), + 3 as ::core::ffi::c_int, + 0 as ::core::ffi::c_int, + ); + } + if add( + (buf as *mut ::core::ffi::c_int).offset(4 as ::core::ffi::c_int as isize), + 4 as ::core::ffi::c_int, + 1 as ::core::ffi::c_int, + ) == 0 + { + add( + (buf as *mut ::core::ffi::c_int).offset(5 as ::core::ffi::c_int as isize), + 5 as ::core::ffi::c_int, + 0 as ::core::ffi::c_int, + ); + } +} diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2024.clang15.snap index 66ae3f2987..ec9143643c 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2024.clang15.snap @@ -93,3 +93,77 @@ pub unsafe extern "C" fn nested_early_returns(mut x: ::core::ffi::c_int) -> ::co } return x; } +#[unsafe(no_mangle)] +pub unsafe extern "C" fn conditional_operator( + sz: ::core::ffi::c_uint, + buf: *mut ::core::ffi::c_int, +) { + let mut x: ::core::ffi::c_int = 0 as ::core::ffi::c_int; + let mut y: ::core::ffi::c_int = 1 as ::core::ffi::c_int; + *if false { &raw mut y } else { &raw mut x } = 10 as ::core::ffi::c_int; + *(buf as *mut ::core::ffi::c_int).offset(2 as ::core::ffi::c_int as isize) = if true { + 2 as ::core::ffi::c_int + } else { + 3 as ::core::ffi::c_int + }; + *(buf as *mut ::core::ffi::c_int).offset(3 as ::core::ffi::c_int as isize) = if false { + 2 as ::core::ffi::c_int + } else { + 3 as ::core::ffi::c_int + }; +} +unsafe extern "C" fn id(mut i: ::core::ffi::c_int) -> ::core::ffi::c_int { + return i; +} +unsafe extern "C" fn add( + mut p: *mut ::core::ffi::c_int, + mut i: ::core::ffi::c_int, + mut r: ::core::ffi::c_int, +) -> ::core::ffi::c_int { + *p += i; + return r; +} +#[unsafe(no_mangle)] +pub unsafe extern "C" fn binary_conditional_operator( + sz: ::core::ffi::c_uint, + buf: *mut ::core::ffi::c_int, +) { + let ref mut c2rust_lvalue_ptr = id(0 as ::core::ffi::c_int); + *(buf as *mut ::core::ffi::c_int).offset(0 as ::core::ffi::c_int as isize) = + if *c2rust_lvalue_ptr != 0 { + *c2rust_lvalue_ptr + } else { + id(1 as ::core::ffi::c_int) + }; + let ref mut c2rust_lvalue_ptr_0 = id(2 as ::core::ffi::c_int); + *(buf as *mut ::core::ffi::c_int).offset(1 as ::core::ffi::c_int as isize) = + if *c2rust_lvalue_ptr_0 != 0 { + *c2rust_lvalue_ptr_0 + } else { + id(3 as ::core::ffi::c_int) + }; + if add( + (buf as *mut ::core::ffi::c_int).offset(2 as ::core::ffi::c_int as isize), + 2 as ::core::ffi::c_int, + 0 as ::core::ffi::c_int, + ) == 0 + { + add( + (buf as *mut ::core::ffi::c_int).offset(3 as ::core::ffi::c_int as isize), + 3 as ::core::ffi::c_int, + 0 as ::core::ffi::c_int, + ); + } + if add( + (buf as *mut ::core::ffi::c_int).offset(4 as ::core::ffi::c_int as isize), + 4 as ::core::ffi::c_int, + 1 as ::core::ffi::c_int, + ) == 0 + { + add( + (buf as *mut ::core::ffi::c_int).offset(5 as ::core::ffi::c_int as isize), + 5 as ::core::ffi::c_int, + 0 as ::core::ffi::c_int, + ); + } +} From 440e67e8002f328cb3e4c455f90126e26933d51f Mon Sep 17 00:00:00 2001 From: Rua Date: Thu, 30 Apr 2026 15:47:46 +0200 Subject: [PATCH 08/12] transpile: Don't use named reference for binary conditionals --- c2rust-transpile/src/translator/mod.rs | 43 ++++++++++++------- ...__transpile@conditions.c.2021.clang15.snap | 12 +++--- ...__transpile@conditions.c.2024.clang15.snap | 12 +++--- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/c2rust-transpile/src/translator/mod.rs b/c2rust-transpile/src/translator/mod.rs index 881e1037d4..17ae215f4f 100644 --- a/c2rust-transpile/src/translator/mod.rs +++ b/c2rust-transpile/src/translator/mod.rs @@ -3360,10 +3360,12 @@ impl<'c> Translation<'c> { } BinaryConditional(ty, lhs, rhs) => { + let rhs = self.convert_expr(ctx, rhs, None)?; + if ctx.is_unused() { - let mut lhs = self.convert_condition(ctx, false, lhs)?; - let rhs = self.convert_expr(ctx, rhs, None)?; - lhs = lhs.merge_unsafe(rhs.is_unsafe()); + let lhs = self + .convert_condition(ctx, false, lhs)? + .merge_unsafe(rhs.is_unsafe()); Ok(lhs.and_then(|val| { WithStmts::new( @@ -3378,19 +3380,28 @@ impl<'c> Translation<'c> { ) })) } else { - self.name_reference_write_read(ctx, lhs)?.try_map( - |NamedReference { - rvalue: lhs_val, .. - }| { - let cond = self.match_bool(ctx, true, ty.ctype, lhs_val.clone())?; - let ite = mk().ifte_expr( - cond, - mk().block(vec![mk().expr_stmt(lhs_val)]), - Some(self.convert_expr(ctx, rhs, None)?.to_expr()), - ); - Ok(ite) - }, - ) + let lhs = self + .convert_expr(ctx.used(), lhs, None)? + .merge_unsafe(rhs.is_unsafe()); + let fresh_name = self.renamer.borrow_mut().fresh(); + + lhs.and_then_try(|lhs| { + let fresh_stmt = mk().local_stmt(Box::new(mk().local( + mk().ident_pat(&fresh_name), + None, + Some(lhs), + ))); + + let cond = + self.match_bool(ctx, true, ty.ctype, mk().ident_expr(&fresh_name))?; + let ite = mk().ifte_expr( + cond, + mk().block(vec![mk().expr_stmt(mk().ident_expr(&fresh_name))]), + Some(rhs.to_expr()), + ); + + Ok(WithStmts::new(vec![fresh_stmt], ite)) + }) } } diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2021.clang15.snap index 70446a3d2e..b1baf9b891 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2021.clang15.snap @@ -128,17 +128,17 @@ pub unsafe extern "C" fn binary_conditional_operator( sz: ::core::ffi::c_uint, buf: *mut ::core::ffi::c_int, ) { - let ref mut c2rust_lvalue_ptr = id(0 as ::core::ffi::c_int); + let c2rust_fresh0 = id(0 as ::core::ffi::c_int); *(buf as *mut ::core::ffi::c_int).offset(0 as ::core::ffi::c_int as isize) = - if *c2rust_lvalue_ptr != 0 { - *c2rust_lvalue_ptr + if c2rust_fresh0 != 0 { + c2rust_fresh0 } else { id(1 as ::core::ffi::c_int) }; - let ref mut c2rust_lvalue_ptr_0 = id(2 as ::core::ffi::c_int); + let c2rust_fresh1 = id(2 as ::core::ffi::c_int); *(buf as *mut ::core::ffi::c_int).offset(1 as ::core::ffi::c_int as isize) = - if *c2rust_lvalue_ptr_0 != 0 { - *c2rust_lvalue_ptr_0 + if c2rust_fresh1 != 0 { + c2rust_fresh1 } else { id(3 as ::core::ffi::c_int) }; diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2024.clang15.snap index ec9143643c..16343532d5 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@conditions.c.2024.clang15.snap @@ -128,17 +128,17 @@ pub unsafe extern "C" fn binary_conditional_operator( sz: ::core::ffi::c_uint, buf: *mut ::core::ffi::c_int, ) { - let ref mut c2rust_lvalue_ptr = id(0 as ::core::ffi::c_int); + let c2rust_fresh0 = id(0 as ::core::ffi::c_int); *(buf as *mut ::core::ffi::c_int).offset(0 as ::core::ffi::c_int as isize) = - if *c2rust_lvalue_ptr != 0 { - *c2rust_lvalue_ptr + if c2rust_fresh0 != 0 { + c2rust_fresh0 } else { id(1 as ::core::ffi::c_int) }; - let ref mut c2rust_lvalue_ptr_0 = id(2 as ::core::ffi::c_int); + let c2rust_fresh1 = id(2 as ::core::ffi::c_int); *(buf as *mut ::core::ffi::c_int).offset(1 as ::core::ffi::c_int as isize) = - if *c2rust_lvalue_ptr_0 != 0 { - *c2rust_lvalue_ptr_0 + if c2rust_fresh1 != 0 { + c2rust_fresh1 } else { id(3 as ::core::ffi::c_int) }; From b104d5112406f1c86804568aa3a7254bbe9cba18 Mon Sep 17 00:00:00 2001 From: Rua Date: Wed, 6 May 2026 16:12:44 +0200 Subject: [PATCH 09/12] transpile: Add more side-effect snapshot tests to `exprs.c` --- c2rust-transpile/tests/snapshots/exprs.c | 37 ++++++++++++- ...shots__transpile@exprs.c.2021.clang15.snap | 55 +++++++++++++++++-- ...shots__transpile@exprs.c.2024.clang15.snap | 55 +++++++++++++++++-- 3 files changed, 132 insertions(+), 15 deletions(-) diff --git a/c2rust-transpile/tests/snapshots/exprs.c b/c2rust-transpile/tests/snapshots/exprs.c index 633e854f9f..7d7c283f3f 100644 --- a/c2rust-transpile/tests/snapshots/exprs.c +++ b/c2rust-transpile/tests/snapshots/exprs.c @@ -2,7 +2,13 @@ int puts(const char *str); static int side_effect(){ puts("the return of side effect"); - return 10; + return 0; +} + +static int* lvalue_side_effect(){ + puts("the return of side effect"); + static int VAL = 42; + return &VAL; } void unary_without_side_effect(){ @@ -20,18 +26,43 @@ void unary_without_side_effect(){ } void unary_with_side_effect(){ - char* arr[1] = {0}; + char *arr[1] = {0}; -side_effect(); +side_effect(); ~side_effect(); !side_effect(); &""[side_effect()]; - *arr[side_effect()]; +} + +void inc_decl_with_rvalue_side_effect() { + int arr[1] = {0}; + + // Increment/decrement, expression value not used ++arr[side_effect()]; --arr[side_effect()]; arr[side_effect()]++; arr[side_effect()]--; + + // Increment/decrement, expression value is used + int pre_inc = ++arr[side_effect()]; + int pre_dec = --arr[side_effect()]; + int post_inc = arr[side_effect()]++; + int post_dec = arr[side_effect()]--; +} + +void inc_decl_with_lvalue_side_effect() { + // Increment/decrement, expression value not used + ++*lvalue_side_effect(); + --*lvalue_side_effect(); + (*lvalue_side_effect())++; + (*lvalue_side_effect())--; + + // Increment/decrement, expression value is used + int pre_inc = ++*lvalue_side_effect(); + int pre_dec = --*lvalue_side_effect(); + int post_inc = (*lvalue_side_effect())++; + int post_dec = (*lvalue_side_effect())--; } void unsigned_compound_desugaring(void) { diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap index 56ee5f78bf..85fcc04684 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap @@ -24,7 +24,12 @@ pub const B: C2Rust_Unnamed = 1; pub const A: C2Rust_Unnamed = 0; unsafe extern "C" fn side_effect() -> ::core::ffi::c_int { puts(b"the return of side effect\0".as_ptr() as *const ::core::ffi::c_char); - return 10 as ::core::ffi::c_int; + return 0 as ::core::ffi::c_int; +} +unsafe extern "C" fn lvalue_side_effect() -> *mut ::core::ffi::c_int { + puts(b"the return of side effect\0".as_ptr() as *const ::core::ffi::c_char); + static mut VAL: ::core::ffi::c_int = 42 as ::core::ffi::c_int; + return &raw mut VAL; } #[no_mangle] pub unsafe extern "C" fn unary_without_side_effect() { @@ -49,11 +54,49 @@ pub unsafe extern "C" fn unary_with_side_effect() { (side_effect() == 0) as ::core::ffi::c_int; (b"\0".as_ptr() as *const ::core::ffi::c_char).offset(side_effect() as isize) as *const ::core::ffi::c_char; - *arr[side_effect() as usize]; - arr[side_effect() as usize] = arr[side_effect() as usize].offset(1); - arr[side_effect() as usize] = arr[side_effect() as usize].offset(-1); - arr[side_effect() as usize] = arr[side_effect() as usize].offset(1); - arr[side_effect() as usize] = arr[side_effect() as usize].offset(-1); +} +#[no_mangle] +pub unsafe extern "C" fn inc_decl_with_rvalue_side_effect() { + let mut arr: [::core::ffi::c_int; 1] = [0 as ::core::ffi::c_int]; + arr[side_effect() as usize] += 1; + arr[side_effect() as usize] -= 1; + arr[side_effect() as usize] += 1; + arr[side_effect() as usize] -= 1; + arr[side_effect() as usize] += 1; + let mut pre_inc: ::core::ffi::c_int = arr[side_effect() as usize]; + arr[side_effect() as usize] -= 1; + let mut pre_dec: ::core::ffi::c_int = arr[side_effect() as usize]; + let c2rust_fresh0 = arr[side_effect() as usize]; + arr[side_effect() as usize] = arr[side_effect() as usize] + 1; + let mut post_inc: ::core::ffi::c_int = c2rust_fresh0; + let c2rust_fresh1 = arr[side_effect() as usize]; + arr[side_effect() as usize] = arr[side_effect() as usize] - 1; + let mut post_dec: ::core::ffi::c_int = c2rust_fresh1; +} +#[no_mangle] +pub unsafe extern "C" fn inc_decl_with_lvalue_side_effect() { + let ref mut c2rust_lvalue_ptr = *lvalue_side_effect(); + *c2rust_lvalue_ptr += 1; + let ref mut c2rust_lvalue_ptr_0 = *lvalue_side_effect(); + *c2rust_lvalue_ptr_0 -= 1; + let ref mut c2rust_lvalue_ptr_1 = *lvalue_side_effect(); + *c2rust_lvalue_ptr_1 += 1; + let ref mut c2rust_lvalue_ptr_2 = *lvalue_side_effect(); + *c2rust_lvalue_ptr_2 -= 1; + let ref mut c2rust_lvalue_ptr_3 = *lvalue_side_effect(); + *c2rust_lvalue_ptr_3 += 1; + let mut pre_inc: ::core::ffi::c_int = *c2rust_lvalue_ptr_3; + let ref mut c2rust_lvalue_ptr_4 = *lvalue_side_effect(); + *c2rust_lvalue_ptr_4 -= 1; + let mut pre_dec: ::core::ffi::c_int = *c2rust_lvalue_ptr_4; + let ref mut c2rust_lvalue_ptr_5 = *lvalue_side_effect(); + let c2rust_fresh2 = *c2rust_lvalue_ptr_5; + *c2rust_lvalue_ptr_5 = *c2rust_lvalue_ptr_5 + 1; + let mut post_inc: ::core::ffi::c_int = c2rust_fresh2; + let ref mut c2rust_lvalue_ptr_6 = *lvalue_side_effect(); + let c2rust_fresh3 = *c2rust_lvalue_ptr_6; + *c2rust_lvalue_ptr_6 = *c2rust_lvalue_ptr_6 - 1; + let mut post_dec: ::core::ffi::c_int = c2rust_fresh3; } #[no_mangle] pub unsafe extern "C" fn unsigned_compound_desugaring() { diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap index 04e6019c9c..82dc3c435a 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap @@ -24,7 +24,12 @@ pub const B: C2Rust_Unnamed = 1; pub const A: C2Rust_Unnamed = 0; unsafe extern "C" fn side_effect() -> ::core::ffi::c_int { puts(b"the return of side effect\0".as_ptr() as *const ::core::ffi::c_char); - return 10 as ::core::ffi::c_int; + return 0 as ::core::ffi::c_int; +} +unsafe extern "C" fn lvalue_side_effect() -> *mut ::core::ffi::c_int { + puts(b"the return of side effect\0".as_ptr() as *const ::core::ffi::c_char); + static mut VAL: ::core::ffi::c_int = 42 as ::core::ffi::c_int; + return &raw mut VAL; } #[unsafe(no_mangle)] pub unsafe extern "C" fn unary_without_side_effect() { @@ -49,11 +54,49 @@ pub unsafe extern "C" fn unary_with_side_effect() { (side_effect() == 0) as ::core::ffi::c_int; (b"\0".as_ptr() as *const ::core::ffi::c_char).offset(side_effect() as isize) as *const ::core::ffi::c_char; - *arr[side_effect() as usize]; - arr[side_effect() as usize] = arr[side_effect() as usize].offset(1); - arr[side_effect() as usize] = arr[side_effect() as usize].offset(-1); - arr[side_effect() as usize] = arr[side_effect() as usize].offset(1); - arr[side_effect() as usize] = arr[side_effect() as usize].offset(-1); +} +#[unsafe(no_mangle)] +pub unsafe extern "C" fn inc_decl_with_rvalue_side_effect() { + let mut arr: [::core::ffi::c_int; 1] = [0 as ::core::ffi::c_int]; + arr[side_effect() as usize] += 1; + arr[side_effect() as usize] -= 1; + arr[side_effect() as usize] += 1; + arr[side_effect() as usize] -= 1; + arr[side_effect() as usize] += 1; + let mut pre_inc: ::core::ffi::c_int = arr[side_effect() as usize]; + arr[side_effect() as usize] -= 1; + let mut pre_dec: ::core::ffi::c_int = arr[side_effect() as usize]; + let c2rust_fresh0 = arr[side_effect() as usize]; + arr[side_effect() as usize] = arr[side_effect() as usize] + 1; + let mut post_inc: ::core::ffi::c_int = c2rust_fresh0; + let c2rust_fresh1 = arr[side_effect() as usize]; + arr[side_effect() as usize] = arr[side_effect() as usize] - 1; + let mut post_dec: ::core::ffi::c_int = c2rust_fresh1; +} +#[unsafe(no_mangle)] +pub unsafe extern "C" fn inc_decl_with_lvalue_side_effect() { + let ref mut c2rust_lvalue_ptr = *lvalue_side_effect(); + *c2rust_lvalue_ptr += 1; + let ref mut c2rust_lvalue_ptr_0 = *lvalue_side_effect(); + *c2rust_lvalue_ptr_0 -= 1; + let ref mut c2rust_lvalue_ptr_1 = *lvalue_side_effect(); + *c2rust_lvalue_ptr_1 += 1; + let ref mut c2rust_lvalue_ptr_2 = *lvalue_side_effect(); + *c2rust_lvalue_ptr_2 -= 1; + let ref mut c2rust_lvalue_ptr_3 = *lvalue_side_effect(); + *c2rust_lvalue_ptr_3 += 1; + let mut pre_inc: ::core::ffi::c_int = *c2rust_lvalue_ptr_3; + let ref mut c2rust_lvalue_ptr_4 = *lvalue_side_effect(); + *c2rust_lvalue_ptr_4 -= 1; + let mut pre_dec: ::core::ffi::c_int = *c2rust_lvalue_ptr_4; + let ref mut c2rust_lvalue_ptr_5 = *lvalue_side_effect(); + let c2rust_fresh2 = *c2rust_lvalue_ptr_5; + *c2rust_lvalue_ptr_5 = *c2rust_lvalue_ptr_5 + 1; + let mut post_inc: ::core::ffi::c_int = c2rust_fresh2; + let ref mut c2rust_lvalue_ptr_6 = *lvalue_side_effect(); + let c2rust_fresh3 = *c2rust_lvalue_ptr_6; + *c2rust_lvalue_ptr_6 = *c2rust_lvalue_ptr_6 - 1; + let mut post_dec: ::core::ffi::c_int = c2rust_fresh3; } #[unsafe(no_mangle)] pub unsafe extern "C" fn unsigned_compound_desugaring() { From f1716bd7d955c115c41a65d9ba77f76eace6b52c Mon Sep 17 00:00:00 2001 From: Rua Date: Wed, 6 May 2026 16:49:03 +0200 Subject: [PATCH 10/12] transpile: Correct uses of `used` in `operators.rs` --- c2rust-transpile/src/translator/operators.rs | 12 ++++----- ...shots__transpile@exprs.c.2021.clang15.snap | 26 ++++++++----------- ...shots__transpile@exprs.c.2024.clang15.snap | 26 ++++++++----------- 3 files changed, 28 insertions(+), 36 deletions(-) diff --git a/c2rust-transpile/src/translator/operators.rs b/c2rust-transpile/src/translator/operators.rs index a61eac8cdd..12c5fc86e9 100644 --- a/c2rust-transpile/src/translator/operators.rs +++ b/c2rust-transpile/src/translator/operators.rs @@ -212,7 +212,7 @@ impl<'c> Translation<'c> { ))) } else { let lhs = self.make_cast( - ctx, + ctx.used(), initial_lhs_type_id, compute_lhs_type_id, WithStmts::new_val(read.clone()), @@ -231,7 +231,7 @@ impl<'c> Translation<'c> { ) })?; - let val = self.make_cast(ctx, compute_res_type_id, lhs_type_id, val)?; + let val = self.make_cast(ctx.used(), compute_res_type_id, lhs_type_id, val)?; Ok(val.map(|val| mk().assign_expr(write.clone(), val))) } @@ -420,7 +420,7 @@ impl<'c> Translation<'c> { .expect("Cannot convert non-assignment operator"); let lhs = self.make_cast( - ctx, + ctx.used(), initial_lhs_type_id, expr_or_comp_type_id, WithStmts::new_val(read.clone()), @@ -440,7 +440,7 @@ impl<'c> Translation<'c> { )?; let val = self.make_cast( - ctx, + ctx.used(), result_type_id, expr_type_id, val, @@ -642,7 +642,7 @@ impl<'c> Translation<'c> { }; self.convert_assignment_operator_with_rhs( - ctx.used(), + ctx, op, ty, arg, @@ -781,7 +781,7 @@ impl<'c> Translation<'c> { .map(|a| mk().unary_expr(UnOp::Not(Default::default()), a))), CUnOp::Not => { - let val = self.convert_condition(ctx, false, arg)?; + let val = self.convert_condition(ctx.used(), false, arg)?; Ok(val.map(|x| mk().cast_expr(x, mk().abs_path_ty(vec!["core", "ffi", "c_int"])))) } CUnOp::Extension => { diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap index 85fcc04684..35aee2e0c1 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap @@ -75,27 +75,23 @@ pub unsafe extern "C" fn inc_decl_with_rvalue_side_effect() { } #[no_mangle] pub unsafe extern "C" fn inc_decl_with_lvalue_side_effect() { + *lvalue_side_effect() += 1; + *lvalue_side_effect() -= 1; + *lvalue_side_effect() += 1; + *lvalue_side_effect() -= 1; let ref mut c2rust_lvalue_ptr = *lvalue_side_effect(); *c2rust_lvalue_ptr += 1; + let mut pre_inc: ::core::ffi::c_int = *c2rust_lvalue_ptr; let ref mut c2rust_lvalue_ptr_0 = *lvalue_side_effect(); *c2rust_lvalue_ptr_0 -= 1; + let mut pre_dec: ::core::ffi::c_int = *c2rust_lvalue_ptr_0; let ref mut c2rust_lvalue_ptr_1 = *lvalue_side_effect(); - *c2rust_lvalue_ptr_1 += 1; - let ref mut c2rust_lvalue_ptr_2 = *lvalue_side_effect(); - *c2rust_lvalue_ptr_2 -= 1; - let ref mut c2rust_lvalue_ptr_3 = *lvalue_side_effect(); - *c2rust_lvalue_ptr_3 += 1; - let mut pre_inc: ::core::ffi::c_int = *c2rust_lvalue_ptr_3; - let ref mut c2rust_lvalue_ptr_4 = *lvalue_side_effect(); - *c2rust_lvalue_ptr_4 -= 1; - let mut pre_dec: ::core::ffi::c_int = *c2rust_lvalue_ptr_4; - let ref mut c2rust_lvalue_ptr_5 = *lvalue_side_effect(); - let c2rust_fresh2 = *c2rust_lvalue_ptr_5; - *c2rust_lvalue_ptr_5 = *c2rust_lvalue_ptr_5 + 1; + let c2rust_fresh2 = *c2rust_lvalue_ptr_1; + *c2rust_lvalue_ptr_1 = *c2rust_lvalue_ptr_1 + 1; let mut post_inc: ::core::ffi::c_int = c2rust_fresh2; - let ref mut c2rust_lvalue_ptr_6 = *lvalue_side_effect(); - let c2rust_fresh3 = *c2rust_lvalue_ptr_6; - *c2rust_lvalue_ptr_6 = *c2rust_lvalue_ptr_6 - 1; + let ref mut c2rust_lvalue_ptr_2 = *lvalue_side_effect(); + let c2rust_fresh3 = *c2rust_lvalue_ptr_2; + *c2rust_lvalue_ptr_2 = *c2rust_lvalue_ptr_2 - 1; let mut post_dec: ::core::ffi::c_int = c2rust_fresh3; } #[no_mangle] diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap index 82dc3c435a..d54e70aeac 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap @@ -75,27 +75,23 @@ pub unsafe extern "C" fn inc_decl_with_rvalue_side_effect() { } #[unsafe(no_mangle)] pub unsafe extern "C" fn inc_decl_with_lvalue_side_effect() { + *lvalue_side_effect() += 1; + *lvalue_side_effect() -= 1; + *lvalue_side_effect() += 1; + *lvalue_side_effect() -= 1; let ref mut c2rust_lvalue_ptr = *lvalue_side_effect(); *c2rust_lvalue_ptr += 1; + let mut pre_inc: ::core::ffi::c_int = *c2rust_lvalue_ptr; let ref mut c2rust_lvalue_ptr_0 = *lvalue_side_effect(); *c2rust_lvalue_ptr_0 -= 1; + let mut pre_dec: ::core::ffi::c_int = *c2rust_lvalue_ptr_0; let ref mut c2rust_lvalue_ptr_1 = *lvalue_side_effect(); - *c2rust_lvalue_ptr_1 += 1; - let ref mut c2rust_lvalue_ptr_2 = *lvalue_side_effect(); - *c2rust_lvalue_ptr_2 -= 1; - let ref mut c2rust_lvalue_ptr_3 = *lvalue_side_effect(); - *c2rust_lvalue_ptr_3 += 1; - let mut pre_inc: ::core::ffi::c_int = *c2rust_lvalue_ptr_3; - let ref mut c2rust_lvalue_ptr_4 = *lvalue_side_effect(); - *c2rust_lvalue_ptr_4 -= 1; - let mut pre_dec: ::core::ffi::c_int = *c2rust_lvalue_ptr_4; - let ref mut c2rust_lvalue_ptr_5 = *lvalue_side_effect(); - let c2rust_fresh2 = *c2rust_lvalue_ptr_5; - *c2rust_lvalue_ptr_5 = *c2rust_lvalue_ptr_5 + 1; + let c2rust_fresh2 = *c2rust_lvalue_ptr_1; + *c2rust_lvalue_ptr_1 = *c2rust_lvalue_ptr_1 + 1; let mut post_inc: ::core::ffi::c_int = c2rust_fresh2; - let ref mut c2rust_lvalue_ptr_6 = *lvalue_side_effect(); - let c2rust_fresh3 = *c2rust_lvalue_ptr_6; - *c2rust_lvalue_ptr_6 = *c2rust_lvalue_ptr_6 - 1; + let ref mut c2rust_lvalue_ptr_2 = *lvalue_side_effect(); + let c2rust_fresh3 = *c2rust_lvalue_ptr_2; + *c2rust_lvalue_ptr_2 = *c2rust_lvalue_ptr_2 - 1; let mut post_dec: ::core::ffi::c_int = c2rust_fresh3; } #[unsafe(no_mangle)] From e97c718f2360177509385b0045267d410324ecfe Mon Sep 17 00:00:00 2001 From: Rua Date: Fri, 19 Jun 2026 12:43:56 +0200 Subject: [PATCH 11/12] transpile: Use raw pointers for lvalues with side effects --- c2rust-transpile/src/translator/named_references.rs | 9 ++++++--- .../snapshots__transpile@exprs.c.2021.clang15.snap | 8 ++++---- .../snapshots__transpile@exprs.c.2024.clang15.snap | 8 ++++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/c2rust-transpile/src/translator/named_references.rs b/c2rust-transpile/src/translator/named_references.rs index 03fbec5fac..dd910a1b72 100644 --- a/c2rust-transpile/src/translator/named_references.rs +++ b/c2rust-transpile/src/translator/named_references.rs @@ -124,11 +124,14 @@ impl<'c> Translation<'c> { let ptr_name = self.renamer.borrow_mut().pick_name("c2rust_lvalue_ptr"); - // let ref mut p = lhs; + // let p = &raw mut lhs; + // Use a raw pointer here so that it doesn't create borrow conflicts and + // doesn't invalidate other pointers. + self.use_feature("raw_ref_op"); let compute_ref = mk().local_stmt(Box::new(mk().local( - mk().mutbl().ident_ref_pat(&ptr_name), + mk().ident_pat(&ptr_name), None, - Some(reference), + Some(mk().mutbl().raw_borrow_expr(reference)), ))); let write = diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap index 35aee2e0c1..7a94c7caf6 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2021.clang15.snap @@ -79,17 +79,17 @@ pub unsafe extern "C" fn inc_decl_with_lvalue_side_effect() { *lvalue_side_effect() -= 1; *lvalue_side_effect() += 1; *lvalue_side_effect() -= 1; - let ref mut c2rust_lvalue_ptr = *lvalue_side_effect(); + let c2rust_lvalue_ptr = &raw mut *lvalue_side_effect(); *c2rust_lvalue_ptr += 1; let mut pre_inc: ::core::ffi::c_int = *c2rust_lvalue_ptr; - let ref mut c2rust_lvalue_ptr_0 = *lvalue_side_effect(); + let c2rust_lvalue_ptr_0 = &raw mut *lvalue_side_effect(); *c2rust_lvalue_ptr_0 -= 1; let mut pre_dec: ::core::ffi::c_int = *c2rust_lvalue_ptr_0; - let ref mut c2rust_lvalue_ptr_1 = *lvalue_side_effect(); + let c2rust_lvalue_ptr_1 = &raw mut *lvalue_side_effect(); let c2rust_fresh2 = *c2rust_lvalue_ptr_1; *c2rust_lvalue_ptr_1 = *c2rust_lvalue_ptr_1 + 1; let mut post_inc: ::core::ffi::c_int = c2rust_fresh2; - let ref mut c2rust_lvalue_ptr_2 = *lvalue_side_effect(); + let c2rust_lvalue_ptr_2 = &raw mut *lvalue_side_effect(); let c2rust_fresh3 = *c2rust_lvalue_ptr_2; *c2rust_lvalue_ptr_2 = *c2rust_lvalue_ptr_2 - 1; let mut post_dec: ::core::ffi::c_int = c2rust_fresh3; diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap index d54e70aeac..165b303c53 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@exprs.c.2024.clang15.snap @@ -79,17 +79,17 @@ pub unsafe extern "C" fn inc_decl_with_lvalue_side_effect() { *lvalue_side_effect() -= 1; *lvalue_side_effect() += 1; *lvalue_side_effect() -= 1; - let ref mut c2rust_lvalue_ptr = *lvalue_side_effect(); + let c2rust_lvalue_ptr = &raw mut *lvalue_side_effect(); *c2rust_lvalue_ptr += 1; let mut pre_inc: ::core::ffi::c_int = *c2rust_lvalue_ptr; - let ref mut c2rust_lvalue_ptr_0 = *lvalue_side_effect(); + let c2rust_lvalue_ptr_0 = &raw mut *lvalue_side_effect(); *c2rust_lvalue_ptr_0 -= 1; let mut pre_dec: ::core::ffi::c_int = *c2rust_lvalue_ptr_0; - let ref mut c2rust_lvalue_ptr_1 = *lvalue_side_effect(); + let c2rust_lvalue_ptr_1 = &raw mut *lvalue_side_effect(); let c2rust_fresh2 = *c2rust_lvalue_ptr_1; *c2rust_lvalue_ptr_1 = *c2rust_lvalue_ptr_1 + 1; let mut post_inc: ::core::ffi::c_int = c2rust_fresh2; - let ref mut c2rust_lvalue_ptr_2 = *lvalue_side_effect(); + let c2rust_lvalue_ptr_2 = &raw mut *lvalue_side_effect(); let c2rust_fresh3 = *c2rust_lvalue_ptr_2; *c2rust_lvalue_ptr_2 = *c2rust_lvalue_ptr_2 - 1; let mut post_dec: ::core::ffi::c_int = c2rust_fresh3; From d4903908c7ff3094ac0524ddd6479c504c56c213 Mon Sep 17 00:00:00 2001 From: akourne Date: Fri, 26 Jun 2026 13:02:56 -0800 Subject: [PATCH 12/12] ci: Remove stale compile_commands cleanup in internal testsuite --- .github/workflows/internal-testsuite.yml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/.github/workflows/internal-testsuite.yml b/.github/workflows/internal-testsuite.yml index 18b36294ed..62c3602aee 100644 --- a/.github/workflows/internal-testsuite.yml +++ b/.github/workflows/internal-testsuite.yml @@ -67,20 +67,6 @@ jobs: rustup toolchain install nightly-2023-04-15 \ --profile minimal --component rustfmt - # TODO(pl): Figure out why json-c fails when caching compile commands - # - name: Get Image Version - # id: get-image-ver - # run: | - # echo "::set-output name=version::$(echo $ImageVersion)" - # shell: bash - - # - name: Cache testsuite compile_commands - # uses: actions/cache@v4 - # with: - # path: | - # ${{ github.workspace }}/tests/integration/tests/**/compile_commands.json - # key: ${{ runner.os }}-ccdb-${{ steps.get-image-ver.outputs.version }} - - name: Provision Debian Packages run: | sudo apt-get -qq update @@ -120,10 +106,8 @@ jobs: (cd tools && cargo build --release --manifest-path split_rust/Cargo.toml) (cd tools && cargo build --release --manifest-path merge_rust/Cargo.toml) - # TODO(pl): figure out why compile_commands.json may cause json-c to fail - name: Run c2rust testsuite run: | - find tests/integration -type f -name compile_commands.json -delete export PATH=$PWD/target/release:$PWD/c2rust-postprocess:$HOME/.local/bin:$PATH echo "PATH=$PATH" export C2RUST_DIR=$PWD