Skip to content

Commit 7047434

Browse files
committed
transpile: emit unsafe inside const block for string transmute
1 parent 01d16da commit 7047434

9 files changed

Lines changed: 74 additions & 61 deletions

c2rust-transpile/src/translator/literals.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl<'c> Translation<'c> {
125125
} else {
126126
// std::mem::transmute::<[u8; size], ctype>(*b"xxxx")
127127
let array_ty = mk().array_ty(mk().ident_ty("u8"), mk().lit_expr(len as u128));
128-
let mut val = transmute_expr(
128+
let val = transmute_expr(
129129
array_ty,
130130
self.convert_type(ty.ctype)?,
131131
mk().unary_expr(UnOp::Deref(Default::default()), val),
@@ -136,11 +136,16 @@ impl<'c> Translation<'c> {
136136
// it will be const-promoted to 'static.
137137
if ctx.needs_address {
138138
self.use_feature("inline_const");
139-
let stmts = vec![mk().expr_stmt(val)];
140-
val = mk().const_block_expr(mk().const_block(stmts));
139+
// An inline `const` block is its own safety context and does not inherit
140+
// the surrounding `unsafe`, so the transmute needs an explicit `unsafe`
141+
// block inside the const block rather than relying on `set_unsafe`.
142+
let unsafe_transmute = mk().unsafe_block_expr(vec![mk().expr_stmt(val)]);
143+
let stmts = vec![mk().expr_stmt(unsafe_transmute)];
144+
let val = mk().const_block_expr(mk().const_block(stmts));
145+
Ok(WithStmts::new_val(val))
146+
} else {
147+
Ok(WithStmts::new_val(val).set_unsafe())
141148
}
142-
143-
Ok(WithStmts::new_val(val).set_unsafe())
144149
}
145150
}
146151
}

c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2021.linux.clang15.snap

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ pub static mut static_array_longer: [wchar_t; 3] =
2727
pub static mut static_array_shorter: [wchar_t; 1] =
2828
unsafe { ::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0") };
2929
#[no_mangle]
30-
pub static mut static_ptr: *const wchar_t = unsafe {
31-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32-
.as_ptr() as *const wchar_t
33-
};
30+
pub static mut static_ptr: *const wchar_t = const {
31+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32+
}
33+
.as_ptr() as *const wchar_t;
3434
#[no_mangle]
3535
pub unsafe extern "C" fn func() {
3636
let mut array: [wchar_t; 2] =
@@ -39,8 +39,9 @@ pub unsafe extern "C" fn func() {
3939
::core::mem::transmute::<[u8; 12], [wchar_t; 3]>(*b"x\0\0\0\0\0\0\0\0\0\0\0");
4040
let mut array_shorter: [wchar_t; 1] =
4141
::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0");
42-
let mut ptr: *const wchar_t =
43-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44-
.as_ptr() as *const wchar_t;
42+
let mut ptr: *const wchar_t = const {
43+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44+
}
45+
.as_ptr() as *const wchar_t;
4546
let mut len: size_t = wcslen(&raw mut array as *mut wchar_t) as size_t;
4647
}

c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2021.linux.clang22.snap

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ pub static mut static_array_longer: [wchar_t; 3] =
2727
pub static mut static_array_shorter: [wchar_t; 1] =
2828
unsafe { ::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0") };
2929
#[no_mangle]
30-
pub static mut static_ptr: *const wchar_t = unsafe {
31-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32-
.as_ptr() as *const wchar_t
33-
};
30+
pub static mut static_ptr: *const wchar_t = const {
31+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32+
}
33+
.as_ptr() as *const wchar_t;
3434
#[no_mangle]
3535
pub unsafe extern "C" fn func() {
3636
let mut array: [wchar_t; 2] =
@@ -39,8 +39,9 @@ pub unsafe extern "C" fn func() {
3939
::core::mem::transmute::<[u8; 12], [wchar_t; 3]>(*b"x\0\0\0\0\0\0\0\0\0\0\0");
4040
let mut array_shorter: [wchar_t; 1] =
4141
::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0");
42-
let mut ptr: *const wchar_t =
43-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44-
.as_ptr() as *const wchar_t;
42+
let mut ptr: *const wchar_t = const {
43+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44+
}
45+
.as_ptr() as *const wchar_t;
4546
let mut len: size_t = wcslen(&raw mut array as *mut wchar_t);
4647
}

c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2021.macos.clang15.snap

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ pub static mut static_array_longer: [wchar_t; 3] =
2727
pub static mut static_array_shorter: [wchar_t; 1] =
2828
unsafe { ::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0") };
2929
#[no_mangle]
30-
pub static mut static_ptr: *const wchar_t = unsafe {
31-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32-
.as_ptr() as *const wchar_t
33-
};
30+
pub static mut static_ptr: *const wchar_t = const {
31+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32+
}
33+
.as_ptr() as *const wchar_t;
3434
#[no_mangle]
3535
pub unsafe extern "C" fn func() {
3636
let mut array: [wchar_t; 2] =
@@ -39,8 +39,9 @@ pub unsafe extern "C" fn func() {
3939
::core::mem::transmute::<[u8; 12], [wchar_t; 3]>(*b"x\0\0\0\0\0\0\0\0\0\0\0");
4040
let mut array_shorter: [wchar_t; 1] =
4141
::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0");
42-
let mut ptr: *const wchar_t =
43-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44-
.as_ptr() as *const wchar_t;
42+
let mut ptr: *const wchar_t = const {
43+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44+
}
45+
.as_ptr() as *const wchar_t;
4546
let mut len: size_t = wcslen(&raw mut array as *mut wchar_t) as size_t;
4647
}

c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2021.macos.clang22.snap

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ pub static mut static_array_longer: [wchar_t; 3] =
2727
pub static mut static_array_shorter: [wchar_t; 1] =
2828
unsafe { ::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0") };
2929
#[no_mangle]
30-
pub static mut static_ptr: *const wchar_t = unsafe {
31-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32-
.as_ptr() as *const wchar_t
33-
};
30+
pub static mut static_ptr: *const wchar_t = const {
31+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32+
}
33+
.as_ptr() as *const wchar_t;
3434
#[no_mangle]
3535
pub unsafe extern "C" fn func() {
3636
let mut array: [wchar_t; 2] =
@@ -39,8 +39,9 @@ pub unsafe extern "C" fn func() {
3939
::core::mem::transmute::<[u8; 12], [wchar_t; 3]>(*b"x\0\0\0\0\0\0\0\0\0\0\0");
4040
let mut array_shorter: [wchar_t; 1] =
4141
::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0");
42-
let mut ptr: *const wchar_t =
43-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44-
.as_ptr() as *const wchar_t;
42+
let mut ptr: *const wchar_t = const {
43+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44+
}
45+
.as_ptr() as *const wchar_t;
4546
let mut len: size_t = wcslen(&raw mut array as *mut wchar_t);
4647
}

c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2024.linux.clang15.snap

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ pub static mut static_array_longer: [wchar_t; 3] =
2727
pub static mut static_array_shorter: [wchar_t; 1] =
2828
unsafe { ::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0") };
2929
#[unsafe(no_mangle)]
30-
pub static mut static_ptr: *const wchar_t = unsafe {
31-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32-
.as_ptr() as *const wchar_t
33-
};
30+
pub static mut static_ptr: *const wchar_t = const {
31+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32+
}
33+
.as_ptr() as *const wchar_t;
3434
#[unsafe(no_mangle)]
3535
pub unsafe extern "C" fn func() {
3636
let mut array: [wchar_t; 2] =
@@ -39,8 +39,9 @@ pub unsafe extern "C" fn func() {
3939
::core::mem::transmute::<[u8; 12], [wchar_t; 3]>(*b"x\0\0\0\0\0\0\0\0\0\0\0");
4040
let mut array_shorter: [wchar_t; 1] =
4141
::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0");
42-
let mut ptr: *const wchar_t =
43-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44-
.as_ptr() as *const wchar_t;
42+
let mut ptr: *const wchar_t = const {
43+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44+
}
45+
.as_ptr() as *const wchar_t;
4546
let mut len: size_t = wcslen(&raw mut array as *mut wchar_t) as size_t;
4647
}

c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2024.linux.clang22.snap

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ pub static mut static_array_longer: [wchar_t; 3] =
2727
pub static mut static_array_shorter: [wchar_t; 1] =
2828
unsafe { ::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0") };
2929
#[unsafe(no_mangle)]
30-
pub static mut static_ptr: *const wchar_t = unsafe {
31-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32-
.as_ptr() as *const wchar_t
33-
};
30+
pub static mut static_ptr: *const wchar_t = const {
31+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32+
}
33+
.as_ptr() as *const wchar_t;
3434
#[unsafe(no_mangle)]
3535
pub unsafe extern "C" fn func() {
3636
let mut array: [wchar_t; 2] =
@@ -39,8 +39,9 @@ pub unsafe extern "C" fn func() {
3939
::core::mem::transmute::<[u8; 12], [wchar_t; 3]>(*b"x\0\0\0\0\0\0\0\0\0\0\0");
4040
let mut array_shorter: [wchar_t; 1] =
4141
::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0");
42-
let mut ptr: *const wchar_t =
43-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44-
.as_ptr() as *const wchar_t;
42+
let mut ptr: *const wchar_t = const {
43+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44+
}
45+
.as_ptr() as *const wchar_t;
4546
let mut len: size_t = wcslen(&raw mut array as *mut wchar_t);
4647
}

c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2024.macos.clang15.snap

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ pub static mut static_array_longer: [wchar_t; 3] =
2727
pub static mut static_array_shorter: [wchar_t; 1] =
2828
unsafe { ::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0") };
2929
#[unsafe(no_mangle)]
30-
pub static mut static_ptr: *const wchar_t = unsafe {
31-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32-
.as_ptr() as *const wchar_t
33-
};
30+
pub static mut static_ptr: *const wchar_t = const {
31+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32+
}
33+
.as_ptr() as *const wchar_t;
3434
#[unsafe(no_mangle)]
3535
pub unsafe extern "C" fn func() {
3636
let mut array: [wchar_t; 2] =
@@ -39,8 +39,9 @@ pub unsafe extern "C" fn func() {
3939
::core::mem::transmute::<[u8; 12], [wchar_t; 3]>(*b"x\0\0\0\0\0\0\0\0\0\0\0");
4040
let mut array_shorter: [wchar_t; 1] =
4141
::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0");
42-
let mut ptr: *const wchar_t =
43-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44-
.as_ptr() as *const wchar_t;
42+
let mut ptr: *const wchar_t = const {
43+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44+
}
45+
.as_ptr() as *const wchar_t;
4546
let mut len: size_t = wcslen(&raw mut array as *mut wchar_t) as size_t;
4647
}

c2rust-transpile/tests/snapshots/snapshots__transpile@wide_strings.c.2024.macos.clang22.snap

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ pub static mut static_array_longer: [wchar_t; 3] =
2727
pub static mut static_array_shorter: [wchar_t; 1] =
2828
unsafe { ::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0") };
2929
#[unsafe(no_mangle)]
30-
pub static mut static_ptr: *const wchar_t = unsafe {
31-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32-
.as_ptr() as *const wchar_t
33-
};
30+
pub static mut static_ptr: *const wchar_t = const {
31+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
32+
}
33+
.as_ptr() as *const wchar_t;
3434
#[unsafe(no_mangle)]
3535
pub unsafe extern "C" fn func() {
3636
let mut array: [wchar_t; 2] =
@@ -39,8 +39,9 @@ pub unsafe extern "C" fn func() {
3939
::core::mem::transmute::<[u8; 12], [wchar_t; 3]>(*b"x\0\0\0\0\0\0\0\0\0\0\0");
4040
let mut array_shorter: [wchar_t; 1] =
4141
::core::mem::transmute::<[u8; 4], [wchar_t; 1]>(*b"x\0\0\0");
42-
let mut ptr: *const wchar_t =
43-
const { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44-
.as_ptr() as *const wchar_t;
42+
let mut ptr: *const wchar_t = const {
43+
unsafe { ::core::mem::transmute::<[u8; 8], [::core::ffi::c_int; 2]>(*b"x\0\0\0\0\0\0\0") }
44+
}
45+
.as_ptr() as *const wchar_t;
4546
let mut len: size_t = wcslen(&raw mut array as *mut wchar_t);
4647
}

0 commit comments

Comments
 (0)