diff --git a/c2rust-transpile/src/c_ast/mod.rs b/c2rust-transpile/src/c_ast/mod.rs index 3011f16632..56b991715f 100644 --- a/c2rust-transpile/src/c_ast/mod.rs +++ b/c2rust-transpile/src/c_ast/mod.rs @@ -691,6 +691,15 @@ impl TypedAstContext { } } + /// Unwraps a constant expression, if there is one. + pub fn unwrap_constant_expr(&self, expr_id: CExprId) -> CExprId { + if let CExprKind::ConstantExpr(_, subexpr, _) = self[expr_id].kind { + subexpr + } else { + expr_id + } + } + /// Unwraps the underlying expression beneath any casts. pub fn unwrap_cast_expr(&self, mut expr_id: CExprId) -> CExprId { while let CExprKind::Paren(_, subexpr) diff --git a/c2rust-transpile/src/translator/literals.rs b/c2rust-transpile/src/translator/literals.rs index e1bfeca9f3..8fb93d02ee 100644 --- a/c2rust-transpile/src/translator/literals.rs +++ b/c2rust-transpile/src/translator/literals.rs @@ -170,7 +170,7 @@ impl<'c> Translation<'c> { return self.convert_expr(ctx, val, override_ty); } - let fresh_name = self.renamer.borrow_mut().fresh(); + let fresh_name = self.renamer.borrow_mut().pick_name("c2rust_lvalue"); let fresh_ty = self.convert_type(override_ty.unwrap_or(qty).ctype)?; // Translate the expression to be assigned to the fresh variable. @@ -259,6 +259,7 @@ impl<'c> Translation<'c> { // * the expr kind being a string literal (`CExprKind::Literal` of a `CLiteral::String`). let is_string_literal = |id: CExprId| { let ty_kind = &self.ast_context.resolve_type(ty).kind; + let id = self.ast_context.unwrap_constant_expr(id); let expr_kind = &self.ast_context.index(id).kind; let is_char_array = matches!(*ty_kind, CTypeKind::Char); let is_str_literal = @@ -267,6 +268,7 @@ impl<'c> Translation<'c> { }; let is_zero_literal = |id: CExprId| { + let id = self.ast_context.unwrap_constant_expr(id); matches!( self.ast_context.index(id).kind, CExprKind::Literal(_, CLiteral::Integer(0, _base)) diff --git a/c2rust-transpile/tests/snapshots/compound_literals.c b/c2rust-transpile/tests/snapshots/compound_literals.c index 840b7ad017..aa489ec5e1 100644 --- a/c2rust-transpile/tests/snapshots/compound_literals.c +++ b/c2rust-transpile/tests/snapshots/compound_literals.c @@ -3,11 +3,8 @@ int *static_single_int_ptr = &((int) { 42 }); int *static_int_ptr_to_array = (int[]) { 42, 9001 }; volatile int *static_volatile_int_ptr_to_array = (int[]) { 42, 9001 }; int (*static_int_array_ptr)[2] = &(int[]) { 42, 9001 }; - -// Currently generates broken Rust code, see -// https://github.com/immunant/c2rust/issues/1410 -//char *static_char_ptr_to_array = (char[]) { "hello" }; -//char (*static_char_array_ptr)[6] = &(char[]) { "hello" }; +char *static_char_ptr_to_array = (char[]) { "hello" }; +char (*static_char_array_ptr)[6] = &(char[]) { "hello" }; #define SINGLE_INT ((int) { 42 }) #define INT_ARRAY ((int[]) { 42, 9001 }) diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@compound_literals.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@compound_literals.c.2021.clang15.snap index 3104780c30..be930cee7b 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@compound_literals.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@compound_literals.c.2021.clang15.snap @@ -14,22 +14,32 @@ expression: cat tests/snapshots/compound_literals.2021.clang15.rs #![feature(raw_ref_op)] #[no_mangle] pub static mut static_single_int: ::core::ffi::c_int = 42; -static mut c2rust_fresh0: ::core::ffi::c_int = 42; +static mut c2rust_lvalue: ::core::ffi::c_int = 42; #[no_mangle] pub static mut static_single_int_ptr: *mut ::core::ffi::c_int = - unsafe { &raw const c2rust_fresh0 as *mut ::core::ffi::c_int }; -static mut c2rust_fresh1: [::core::ffi::c_int; 2] = [42, 9001]; + unsafe { &raw const c2rust_lvalue as *mut ::core::ffi::c_int }; +static mut c2rust_lvalue_0: [::core::ffi::c_int; 2] = [42, 9001]; #[no_mangle] pub static mut static_int_ptr_to_array: *mut ::core::ffi::c_int = - unsafe { &raw const c2rust_fresh1 as *mut ::core::ffi::c_int }; -static mut c2rust_fresh2: [::core::ffi::c_int; 2] = [42, 9001]; + unsafe { &raw const c2rust_lvalue_0 as *mut ::core::ffi::c_int }; +static mut c2rust_lvalue_1: [::core::ffi::c_int; 2] = [42, 9001]; #[no_mangle] pub static mut static_volatile_int_ptr_to_array: *mut ::core::ffi::c_int = - unsafe { &raw const c2rust_fresh2 as *mut ::core::ffi::c_int as *mut ::core::ffi::c_int }; -static mut c2rust_fresh3: [::core::ffi::c_int; 2] = [42, 9001]; + unsafe { &raw const c2rust_lvalue_1 as *mut ::core::ffi::c_int as *mut ::core::ffi::c_int }; +static mut c2rust_lvalue_2: [::core::ffi::c_int; 2] = [42, 9001]; #[no_mangle] pub static mut static_int_array_ptr: *mut [::core::ffi::c_int; 2] = - unsafe { &raw const c2rust_fresh3 as *mut [::core::ffi::c_int; 2] }; + unsafe { &raw const c2rust_lvalue_2 as *mut [::core::ffi::c_int; 2] }; +static mut c2rust_lvalue_3: [::core::ffi::c_char; 6] = + unsafe { ::core::mem::transmute::<[u8; 6], [::core::ffi::c_char; 6]>(*b"hello\0") }; +#[no_mangle] +pub static mut static_char_ptr_to_array: *mut ::core::ffi::c_char = + unsafe { &raw const c2rust_lvalue_3 as *mut ::core::ffi::c_char }; +static mut c2rust_lvalue_4: [::core::ffi::c_char; 6] = + unsafe { ::core::mem::transmute::<[u8; 6], [::core::ffi::c_char; 6]>(*b"hello\0") }; +#[no_mangle] +pub static mut static_char_array_ptr: *mut [::core::ffi::c_char; 6] = + unsafe { &raw const c2rust_lvalue_4 as *mut [::core::ffi::c_char; 6] }; pub const SINGLE_INT: ::core::ffi::c_int = 42 as ::core::ffi::c_int; pub const INT_ARRAY: [::core::ffi::c_int; 2] = [42 as ::core::ffi::c_int, 9001 as ::core::ffi::c_int]; @@ -38,22 +48,22 @@ pub const CHAR_ARRAY: [::core::ffi::c_char; 6] = #[no_mangle] pub unsafe extern "C" fn local_compound_literals() { let mut single_int: ::core::ffi::c_int = 42 as ::core::ffi::c_int; - let mut c2rust_fresh4: ::core::ffi::c_int = 42 as ::core::ffi::c_int; - let mut single_int_ptr: *mut ::core::ffi::c_int = &raw mut c2rust_fresh4; - let mut c2rust_fresh5: [::core::ffi::c_int; 2] = + let mut c2rust_lvalue_5: ::core::ffi::c_int = 42 as ::core::ffi::c_int; + let mut single_int_ptr: *mut ::core::ffi::c_int = &raw mut c2rust_lvalue_5; + let mut c2rust_lvalue_6: [::core::ffi::c_int; 2] = [42 as ::core::ffi::c_int, 9001 as ::core::ffi::c_int]; let mut int_ptr_to_array: *mut ::core::ffi::c_int = - &raw mut c2rust_fresh5 as *mut ::core::ffi::c_int; - let mut c2rust_fresh6: [::core::ffi::c_char; 6] = + &raw mut c2rust_lvalue_6 as *mut ::core::ffi::c_int; + let mut c2rust_lvalue_7: [::core::ffi::c_char; 6] = ::core::mem::transmute::<[u8; 6], [::core::ffi::c_char; 6]>(*b"hello\0"); let mut char_ptr_to_array: *mut ::core::ffi::c_char = - &raw mut c2rust_fresh6 as *mut ::core::ffi::c_char; - let mut c2rust_fresh7: [::core::ffi::c_int; 2] = + &raw mut c2rust_lvalue_7 as *mut ::core::ffi::c_char; + let mut c2rust_lvalue_8: [::core::ffi::c_int; 2] = [42 as ::core::ffi::c_int, 9001 as ::core::ffi::c_int]; - let mut int_array_ptr: *mut [::core::ffi::c_int; 2] = &raw mut c2rust_fresh7; - let mut c2rust_fresh8: [::core::ffi::c_char; 6] = + let mut int_array_ptr: *mut [::core::ffi::c_int; 2] = &raw mut c2rust_lvalue_8; + let mut c2rust_lvalue_9: [::core::ffi::c_char; 6] = ::core::mem::transmute::<[u8; 6], [::core::ffi::c_char; 6]>(*b"hello\0"); - let mut char_array_ptr: *mut [::core::ffi::c_char; 6] = &raw mut c2rust_fresh8; + let mut char_array_ptr: *mut [::core::ffi::c_char; 6] = &raw mut c2rust_lvalue_9; let mut macro_single_int: ::core::ffi::c_int = SINGLE_INT; let mut macro_single_int_ptr: *mut ::core::ffi::c_int = &mut SINGLE_INT as *mut ::core::ffi::c_int; diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@compound_literals.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@compound_literals.c.2024.clang15.snap index d1e0e2f33d..0075694d55 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@compound_literals.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@compound_literals.c.2024.clang15.snap @@ -14,22 +14,32 @@ expression: cat tests/snapshots/compound_literals.2024.clang15.rs )] #[unsafe(no_mangle)] pub static mut static_single_int: ::core::ffi::c_int = 42; -static mut c2rust_fresh0: ::core::ffi::c_int = 42; +static mut c2rust_lvalue: ::core::ffi::c_int = 42; #[unsafe(no_mangle)] pub static mut static_single_int_ptr: *mut ::core::ffi::c_int = - &raw const c2rust_fresh0 as *mut ::core::ffi::c_int; -static mut c2rust_fresh1: [::core::ffi::c_int; 2] = [42, 9001]; + &raw const c2rust_lvalue as *mut ::core::ffi::c_int; +static mut c2rust_lvalue_0: [::core::ffi::c_int; 2] = [42, 9001]; #[unsafe(no_mangle)] pub static mut static_int_ptr_to_array: *mut ::core::ffi::c_int = - &raw const c2rust_fresh1 as *mut ::core::ffi::c_int; -static mut c2rust_fresh2: [::core::ffi::c_int; 2] = [42, 9001]; + &raw const c2rust_lvalue_0 as *mut ::core::ffi::c_int; +static mut c2rust_lvalue_1: [::core::ffi::c_int; 2] = [42, 9001]; #[unsafe(no_mangle)] pub static mut static_volatile_int_ptr_to_array: *mut ::core::ffi::c_int = - &raw const c2rust_fresh2 as *mut ::core::ffi::c_int as *mut ::core::ffi::c_int; -static mut c2rust_fresh3: [::core::ffi::c_int; 2] = [42, 9001]; + &raw const c2rust_lvalue_1 as *mut ::core::ffi::c_int as *mut ::core::ffi::c_int; +static mut c2rust_lvalue_2: [::core::ffi::c_int; 2] = [42, 9001]; #[unsafe(no_mangle)] pub static mut static_int_array_ptr: *mut [::core::ffi::c_int; 2] = - &raw const c2rust_fresh3 as *mut [::core::ffi::c_int; 2]; + &raw const c2rust_lvalue_2 as *mut [::core::ffi::c_int; 2]; +static mut c2rust_lvalue_3: [::core::ffi::c_char; 6] = + unsafe { ::core::mem::transmute::<[u8; 6], [::core::ffi::c_char; 6]>(*b"hello\0") }; +#[unsafe(no_mangle)] +pub static mut static_char_ptr_to_array: *mut ::core::ffi::c_char = + &raw const c2rust_lvalue_3 as *mut ::core::ffi::c_char; +static mut c2rust_lvalue_4: [::core::ffi::c_char; 6] = + unsafe { ::core::mem::transmute::<[u8; 6], [::core::ffi::c_char; 6]>(*b"hello\0") }; +#[unsafe(no_mangle)] +pub static mut static_char_array_ptr: *mut [::core::ffi::c_char; 6] = + &raw const c2rust_lvalue_4 as *mut [::core::ffi::c_char; 6]; pub const SINGLE_INT: ::core::ffi::c_int = 42 as ::core::ffi::c_int; pub const INT_ARRAY: [::core::ffi::c_int; 2] = [42 as ::core::ffi::c_int, 9001 as ::core::ffi::c_int]; @@ -38,22 +48,22 @@ pub const CHAR_ARRAY: [::core::ffi::c_char; 6] = #[unsafe(no_mangle)] pub unsafe extern "C" fn local_compound_literals() { let mut single_int: ::core::ffi::c_int = 42 as ::core::ffi::c_int; - let mut c2rust_fresh4: ::core::ffi::c_int = 42 as ::core::ffi::c_int; - let mut single_int_ptr: *mut ::core::ffi::c_int = &raw mut c2rust_fresh4; - let mut c2rust_fresh5: [::core::ffi::c_int; 2] = + let mut c2rust_lvalue_5: ::core::ffi::c_int = 42 as ::core::ffi::c_int; + let mut single_int_ptr: *mut ::core::ffi::c_int = &raw mut c2rust_lvalue_5; + let mut c2rust_lvalue_6: [::core::ffi::c_int; 2] = [42 as ::core::ffi::c_int, 9001 as ::core::ffi::c_int]; let mut int_ptr_to_array: *mut ::core::ffi::c_int = - &raw mut c2rust_fresh5 as *mut ::core::ffi::c_int; - let mut c2rust_fresh6: [::core::ffi::c_char; 6] = + &raw mut c2rust_lvalue_6 as *mut ::core::ffi::c_int; + let mut c2rust_lvalue_7: [::core::ffi::c_char; 6] = ::core::mem::transmute::<[u8; 6], [::core::ffi::c_char; 6]>(*b"hello\0"); let mut char_ptr_to_array: *mut ::core::ffi::c_char = - &raw mut c2rust_fresh6 as *mut ::core::ffi::c_char; - let mut c2rust_fresh7: [::core::ffi::c_int; 2] = + &raw mut c2rust_lvalue_7 as *mut ::core::ffi::c_char; + let mut c2rust_lvalue_8: [::core::ffi::c_int; 2] = [42 as ::core::ffi::c_int, 9001 as ::core::ffi::c_int]; - let mut int_array_ptr: *mut [::core::ffi::c_int; 2] = &raw mut c2rust_fresh7; - let mut c2rust_fresh8: [::core::ffi::c_char; 6] = + let mut int_array_ptr: *mut [::core::ffi::c_int; 2] = &raw mut c2rust_lvalue_8; + let mut c2rust_lvalue_9: [::core::ffi::c_char; 6] = ::core::mem::transmute::<[u8; 6], [::core::ffi::c_char; 6]>(*b"hello\0"); - let mut char_array_ptr: *mut [::core::ffi::c_char; 6] = &raw mut c2rust_fresh8; + let mut char_array_ptr: *mut [::core::ffi::c_char; 6] = &raw mut c2rust_lvalue_9; let mut macro_single_int: ::core::ffi::c_int = SINGLE_INT; let mut macro_single_int_ptr: *mut ::core::ffi::c_int = &mut SINGLE_INT as *mut ::core::ffi::c_int; diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@empty_init.c.2021.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@empty_init.c.2021.clang15.snap index 67d940960e..879ed4bf00 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@empty_init.c.2021.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@empty_init.c.2021.clang15.snap @@ -23,11 +23,11 @@ pub struct Foo_s { pub x: ::core::ffi::c_int, } pub type Foo_t = Foo_s; -static mut c2rust_fresh0: Scope = Scope { +static mut c2rust_lvalue: Scope = Scope { next: ::core::ptr::null_mut::(), }; #[no_mangle] -pub static mut scope: *mut Scope = unsafe { &raw const c2rust_fresh0 as *mut Scope }; +pub static mut scope: *mut Scope = unsafe { &raw const c2rust_lvalue as *mut Scope }; #[no_mangle] pub unsafe extern "C" fn foo() { let mut f: Foo_t = Foo_t { x: 0 }; diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@empty_init.c.2024.clang15.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@empty_init.c.2024.clang15.snap index bac8bb8a63..4c884273fa 100644 --- a/c2rust-transpile/tests/snapshots/snapshots__transpile@empty_init.c.2024.clang15.snap +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@empty_init.c.2024.clang15.snap @@ -23,11 +23,11 @@ pub struct Foo_s { pub x: ::core::ffi::c_int, } pub type Foo_t = Foo_s; -static mut c2rust_fresh0: Scope = Scope { +static mut c2rust_lvalue: Scope = Scope { next: ::core::ptr::null_mut::(), }; #[unsafe(no_mangle)] -pub static mut scope: *mut Scope = &raw const c2rust_fresh0 as *mut Scope; +pub static mut scope: *mut Scope = &raw const c2rust_lvalue as *mut Scope; #[unsafe(no_mangle)] pub unsafe extern "C" fn foo() { let mut f: Foo_t = Foo_t { x: 0 };