Skip to content

Commit 43aa6a7

Browse files
committed
ptr::replace: make calls on ZST null ptr not UB
1 parent e22dab3 commit 43aa6a7

1 file changed

Lines changed: 8 additions & 1 deletion

File tree

library/core/src/ptr/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1541,7 +1541,7 @@ pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
15411541
// SAFETY: the caller must guarantee that `dst` is valid to be
15421542
// cast to a mutable reference (valid for writes, aligned, initialized),
15431543
// and cannot overlap `src` since `dst` must point to a distinct
1544-
// allocation.
1544+
// allocation. We are excluding null (with a ZST check) before creating a reference.
15451545
unsafe {
15461546
ub_checks::assert_unsafe_precondition!(
15471547
check_language_ub,
@@ -1552,6 +1552,13 @@ pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
15521552
is_zst: bool = T::IS_ZST,
15531553
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
15541554
);
1555+
if T::IS_ZST {
1556+
// `dst` may be valid for read and writes while also being null, in which case we cannot
1557+
// call `mem::replace`. However, we also don't have to actually do anything since there
1558+
// isn't actually any data to be copied anyway. All values of type `T` are
1559+
// bit-identical, so we can just return `src`` here.
1560+
return src;
1561+
}
15551562
mem::replace(&mut *dst, src)
15561563
}
15571564
}

0 commit comments

Comments
 (0)