Skip to content

Commit

Permalink
(c2rust-analyze) For the array safe transmutability rule, require t…
Browse files Browse the repository at this point in the history
…han `N > 0` to avoid ZSTs, as then the rule would be unsound.
  • Loading branch information
kkysen committed Jun 8, 2023
1 parent 1317e03 commit 6b3bdd8
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 7 deletions.
16 changes: 13 additions & 3 deletions c2rust-analyze/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ impl<'a, T: ?Sized> PhantomLifetime<'a> for T {}
/// * `A ~ B => *A ~ *B`
/// * `uN ~ iN`, `iN ~ uN`, where `N` is an integer width
/// * `A ~ B => [A] ~ B`
/// * `A ~ B => [A; N] ~ B`, where `const N: usize`
/// * `A ~ B, N > 0 => [A; N] ~ B`, where `const N: usize`
///
/// Thus, [`true`] means it is definitely transmutable,
/// while [`false`] means it may not be transmutable.
Expand All @@ -393,8 +393,18 @@ pub fn is_transmutable_to<'tcx>(from: Ty<'tcx>, to: Ty<'tcx>) -> bool {
}
};

let one_way_transmutable = || match from.kind() {
&ty::Array(from, _) | &ty::Slice(from) => is_transmutable_to(from, to),
let one_way_transmutable = || match *from.kind() {
ty::Array(from, n) => {
is_transmutable_to(from, to) && {
let is_zero = n
.kind()
.try_to_scalar_int()
.map(|i| i.is_null())
.unwrap_or(false);
!is_zero
}
}
ty::Slice(from) => is_transmutable_to(from, to),
_ => false,
};

Expand Down
8 changes: 4 additions & 4 deletions c2rust-analyze/tests/analyze/string_casts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ pub fn cast_slice_ptr_to_ptr(s: *const [u8]) {
/// and `core::ptr::addr_of!` do work.

#[cfg(any())]
pub fn cast_array_to_ptr(s: &[u8; 0]) {
pub fn cast_array_to_ptr(s: &[u8; 1]) {
s as *const u8;
}

pub fn cast_array_to_ptr_explicit(s: &[u8; 0]) {
pub fn cast_array_to_ptr_explicit(s: &[u8; 1]) {
std::ptr::addr_of!(*s) as *const u8;
}

#[cfg(any())]
pub fn cast_from_literal() {
b"" as *const u8 as *const core::ffi::c_char;
b"\0" as *const u8 as *const core::ffi::c_char;
}

pub fn cast_from_literal_explicit() {
std::ptr::addr_of!(*b"") as *const u8 as *const core::ffi::c_char;
std::ptr::addr_of!(*b"\0") as *const u8 as *const core::ffi::c_char;
}

0 comments on commit 6b3bdd8

Please sign in to comment.