From 44204ac5b9c715c8252c68bca95af30499b3f946 Mon Sep 17 00:00:00 2001 From: Rua Date: Fri, 17 Apr 2026 00:20:34 +0200 Subject: [PATCH 1/2] transpile: Make vector init expression `unsafe` in const contexts --- c2rust-transpile/src/translator/builtins.rs | 6 +++--- c2rust-transpile/src/translator/simd.rs | 17 +++++++++++------ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/c2rust-transpile/src/translator/builtins.rs b/c2rust-transpile/src/translator/builtins.rs index 093c5345a7..92f6e2dc61 100644 --- a/c2rust-transpile/src/translator/builtins.rs +++ b/c2rust-transpile/src/translator/builtins.rs @@ -427,7 +427,7 @@ impl<'c> Translation<'c> { warn!("{builtin_name} has no Rust equivalent; emitting null pointer"); } let level = self.convert_expr(ctx.unused(), args[0], None)?; - Ok(level.and_then(|_| -> TranslationResult<_> { + Ok(level.and_then(|_| { let void_ty = mk().abs_path_ty(vec!["core", "ffi", "c_void"]); let type_args = mk().angle_bracketed_args(vec![void_ty]); let null_expr = mk().call_expr( @@ -438,8 +438,8 @@ impl<'c> Translation<'c> { ]), vec![], ); - Ok(WithStmts::new_val(null_expr)) - })?) + WithStmts::new_val(null_expr) + })) } "__builtin_extract_return_addr" | "__builtin_frob_return_addr" => { diff --git a/c2rust-transpile/src/translator/simd.rs b/c2rust-transpile/src/translator/simd.rs index 3481084212..91fee866a1 100644 --- a/c2rust-transpile/src/translator/simd.rs +++ b/c2rust-transpile/src/translator/simd.rs @@ -295,11 +295,13 @@ impl<'c> Translation<'c> { ) -> TranslationResult>> { let param_translation = self.convert_exprs(ctx, ids, None)?; param_translation.and_then_try(|mut params| { + let mut is_unsafe = false; + // When used in a const context, we cannot call the standard functions since they // are not const and so we are forced to transmute let call = if ctx.is_const { + is_unsafe = true; let tuple = mk().tuple_expr(params); - transmute_expr(mk().infer_ty(), mk().infer_ty(), tuple) } else { let fn_call_name = match (&self.ast_context[ctype].kind, len) { @@ -332,14 +334,17 @@ impl<'c> Translation<'c> { mk().call_expr(mk().ident_expr(fn_call_name), params) }; - if ctx.is_used() { - Ok(WithStmts::new_val(call)) + let mut val = if ctx.is_used() { + WithStmts::new_val(call) } else { - Ok(WithStmts::new( + WithStmts::new( vec![mk().expr_stmt(call)], self.panic_or_err("No value for unused shuffle vector return"), - )) - } + ) + }; + val.merge_unsafe(is_unsafe); + + Ok(val) }) } From 6f8ad2ef6ce45b5f0125bca842f4f15e46eb3a7c Mon Sep 17 00:00:00 2001 From: Rua Date: Fri, 17 Apr 2026 00:20:47 +0200 Subject: [PATCH 2/2] transpile: Remove `static_initializer_is_unsafe` --- c2rust-transpile/src/translator/mod.rs | 53 -------------------------- 1 file changed, 53 deletions(-) diff --git a/c2rust-transpile/src/translator/mod.rs b/c2rust-transpile/src/translator/mod.rs index a0a9de1091..438ccb1414 100644 --- a/c2rust-transpile/src/translator/mod.rs +++ b/c2rust-transpile/src/translator/mod.rs @@ -1631,53 +1631,6 @@ impl<'c> Translation<'c> { } } - fn static_initializer_is_unsafe(&self, expr_id: Option, qty: CQualTypeId) -> bool { - // SIMD types are always unsafe in statics - match self.ast_context.resolve_type(qty.ctype).kind { - CTypeKind::Vector(..) => return true, - CTypeKind::ConstantArray(ctype, ..) => { - let kind = &self.ast_context.resolve_type(ctype).kind; - - if let CTypeKind::Vector(..) = kind { - return true; - } - } - _ => {} - } - - // Get the initializer if there is one - let expr_id = match expr_id { - Some(expr_id) => expr_id, - None => return false, - }; - - // Look for code which can only be translated unsafely - let iter = DFExpr::new(&self.ast_context, expr_id.into()); - - for i in iter { - let expr_id = match i { - SomeId::Expr(expr_id) => expr_id, - _ => unreachable!("Found static initializer type other than expr"), - }; - - use CExprKind::*; - match self.ast_context[expr_id].kind { - ImplicitCast(_, _, cast_kind, _, _) | ExplicitCast(_, _, cast_kind, _, _) => { - use CastKind::*; - match cast_kind { - IntegralToPointer | FunctionToPointerDecay | PointerToIntegral => { - return true; - } - _ => {} - } - } - _ => {} - } - } - - false - } - /// The purpose of this function is to decide on whether or not a static initializer's /// translation is able to be compiled as a valid rust static initializer fn static_initializer_is_uncompilable( @@ -2126,12 +2079,6 @@ impl<'c> Translation<'c> { let mut items = init.stmts_to_items().ok_or_else(|| { format_err!("Expected only item statements in static initializer") })?; - - // TODO: Replace this by relying entirely on - // WithStmts.is_unsafe() of the translated variable - if self.static_initializer_is_unsafe(initializer, typ) { - init.set_unsafe() - } let init = init.wrap_unsafe().to_pure_expr().unwrap(); let item = static_def.span(span).static_item(new_name, ty, init); items.push(item);