Skip to content

Commit 217ae42

Browse files
authored
Avoid mutable transmute in string literals (#1360)
* Fixes #1154 Going with the fix proposed in #743 (comment). The original code would set the array size to 1 if it wasn't statically determined by the type. I'm not sure in which situations that would happen, it still seems suspicious. But to avoid breaking anything I don't understand, I separated it off, and applied my fix only to the case where the size is known.
2 parents be5984d + 636b554 commit 217ae42

26 files changed

+45
-80
lines changed

c2rust-transpile/src/translator/literals.rs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -153,30 +153,25 @@ impl<'c> Translation<'c> {
153153

154154
CLiteral::String(ref val, width) => {
155155
let mut val = val.to_owned();
156-
157156
let num_elems = match self.ast_context.resolve_type(ty.ctype).kind {
158-
// Match the literal size to the expected size padding with zeros as needed
159-
CTypeKind::ConstantArray(_elem_ty, size) => size,
160-
// zero terminator
161-
_ => 1,
157+
CTypeKind::ConstantArray(_elem_ty, num_elems) => num_elems,
158+
ref kind => {
159+
panic!("String literal with unknown size: {val:?}, kind = {kind:?}")
160+
}
162161
};
162+
163+
// Match the literal size to the expected size padding with zeros as needed
163164
let size = num_elems * (width as usize);
164165
val.resize(size, 0);
165166

167+
// std::mem::transmute::<[u8; size], ctype>(*b"xxxx")
166168
let u8_ty = mk().path_ty(vec!["u8"]);
167169
let width_lit = mk().lit_expr(mk().int_unsuffixed_lit(val.len() as u128));
168-
let array_ty = mk().array_ty(u8_ty, width_lit);
169-
let source_ty = mk().ref_ty(array_ty);
170-
let mutbl = if ty.qualifiers.is_const {
171-
Mutability::Immutable
172-
} else {
173-
Mutability::Mutable
174-
};
175-
let target_ty = mk().set_mutbl(mutbl).ref_ty(self.convert_type(ty.ctype)?);
176-
let byte_literal = mk().lit_expr(val);
177-
let pointer = transmute_expr(source_ty, target_ty, byte_literal);
178-
let array = mk().unary_expr(UnOp::Deref(Default::default()), pointer);
179-
Ok(WithStmts::new_unsafe_val(array))
170+
Ok(WithStmts::new_unsafe_val(transmute_expr(
171+
mk().array_ty(u8_ty, width_lit),
172+
self.convert_type(ty.ctype)?,
173+
mk().unary_expr("*", mk().lit_expr(val)),
174+
)))
180175
}
181176
}
182177
}

c2rust-transpile/src/translator/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,6 @@ impl<'c> Translation<'c> {
12331233
"non_camel_case_types",
12341234
"non_snake_case",
12351235
"dead_code",
1236-
"mutable_transmutes",
12371236
"unused_mut",
12381237
"unused_assignments",
12391238
],

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ input_file: c2rust-transpile/tests/snapshots/arch-specific/dummy.c
55
---
66
#![allow(
77
dead_code,
8-
mutable_transmutes,
98
non_camel_case_types,
109
non_snake_case,
1110
non_upper_case_globals,

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ input_file: c2rust-transpile/tests/snapshots/arch-specific/spin.c
55
---
66
#![allow(
77
dead_code,
8-
mutable_transmutes,
98
non_camel_case_types,
109
non_snake_case,
1110
non_upper_case_globals,

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ input_file: c2rust-transpile/tests/snapshots/os-specific/macros.c
55
---
66
#![allow(
77
dead_code,
8-
mutable_transmutes,
98
non_camel_case_types,
109
non_snake_case,
1110
non_upper_case_globals,
@@ -32,7 +31,7 @@ pub unsafe extern "C" fn size_of_const() -> std::ffi::c_int {
3231
}
3332
pub const SIZE: usize = ::core::mem::size_of::<[std::ffi::c_int; 10]>();
3433
pub const POS: [std::ffi::c_char; 3] =
35-
unsafe { *::core::mem::transmute::<&[u8; 3], &[std::ffi::c_char; 3]>(b"\"]\0") };
34+
unsafe { ::core::mem::transmute::<[u8; 3], [std::ffi::c_char; 3]>(*b"\"]\0") };
3635
#[no_mangle]
3736
pub unsafe extern "C" fn memcpy_str_literal(mut out: *mut std::ffi::c_char) {
3837
memcpy(

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ input_file: c2rust-transpile/tests/snapshots/os-specific/rnd.c
55
---
66
#![allow(
77
dead_code,
8-
mutable_transmutes,
98
non_camel_case_types,
109
non_snake_case,
1110
non_upper_case_globals,

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ input_file: c2rust-transpile/tests/snapshots/os-specific/rotate.c
55
---
66
#![allow(
77
dead_code,
8-
mutable_transmutes,
98
non_camel_case_types,
109
non_snake_case,
1110
non_upper_case_globals,

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ input_file: c2rust-transpile/tests/snapshots/platform-specific/types.c
66
---
77
#![allow(
88
dead_code,
9-
mutable_transmutes,
109
non_camel_case_types,
1110
non_snake_case,
1211
non_upper_case_globals,

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ input_file: c2rust-transpile/tests/snapshots/os-specific/macros.c
55
---
66
#![allow(
77
dead_code,
8-
mutable_transmutes,
98
non_camel_case_types,
109
non_snake_case,
1110
non_upper_case_globals,
@@ -33,7 +32,7 @@ pub unsafe extern "C" fn size_of_const() -> std::ffi::c_int {
3332
}
3433
pub const SIZE: usize = ::core::mem::size_of::<[std::ffi::c_int; 10]>();
3534
pub const POS: [std::ffi::c_char; 3] =
36-
unsafe { *::core::mem::transmute::<&[u8; 3], &[std::ffi::c_char; 3]>(b"\"]\0") };
35+
unsafe { ::core::mem::transmute::<[u8; 3], [std::ffi::c_char; 3]>(*b"\"]\0") };
3736
#[no_mangle]
3837
pub unsafe extern "C" fn memcpy_str_literal(mut out: *mut std::ffi::c_char) {
3938
memcpy(

c2rust-transpile/tests/snapshots/[email protected]

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ input_file: c2rust-transpile/tests/snapshots/os-specific/rnd.c
55
---
66
#![allow(
77
dead_code,
8-
mutable_transmutes,
98
non_camel_case_types,
109
non_snake_case,
1110
non_upper_case_globals,

0 commit comments

Comments
 (0)