Skip to content

Commit

Permalink
clean up const stability around UB checks
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Nov 16, 2024
1 parent ee78601 commit e4fb962
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 24 deletions.
12 changes: 6 additions & 6 deletions core/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4013,9 +4013,9 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
count: usize = count,
) => {
let zero_size = count == 0 || size == 0;
ub_checks::is_aligned_and_not_null(src, align, zero_size)
&& ub_checks::is_aligned_and_not_null(dst, align, zero_size)
&& ub_checks::is_nonoverlapping(src, dst, size, count)
ub_checks::maybe_is_aligned_and_not_null(src, align, zero_size)
&& ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size)
&& ub_checks::maybe_is_nonoverlapping(src, dst, size, count)
}
);

Expand Down Expand Up @@ -4119,8 +4119,8 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
align: usize = align_of::<T>(),
zero_size: bool = T::IS_ZST || count == 0,
) =>
ub_checks::is_aligned_and_not_null(src, align, zero_size)
&& ub_checks::is_aligned_and_not_null(dst, align, zero_size)
ub_checks::maybe_is_aligned_and_not_null(src, align, zero_size)
&& ub_checks::maybe_is_aligned_and_not_null(dst, align, zero_size)
);
copy(src, dst, count)
}
Expand Down Expand Up @@ -4201,7 +4201,7 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
addr: *const () = dst as *const (),
align: usize = align_of::<T>(),
zero_size: bool = T::IS_ZST || count == 0,
) => ub_checks::is_aligned_and_not_null(addr, align, zero_size)
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, zero_size)
);
write_bytes(dst, val, count)
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(const_exact_div))]
#![cfg_attr(bootstrap, feature(const_fmt_arguments_new))]
#![cfg_attr(bootstrap, feature(const_ub_checks))]
#![feature(array_ptr_get)]
#![feature(asm_experimental_arch)]
#![feature(const_align_of_val)]
Expand All @@ -131,7 +132,6 @@
#![feature(const_type_id)]
#![feature(const_type_name)]
#![feature(const_typed_swap)]
#![feature(const_ub_checks)]
#![feature(core_intrinsics)]
#![feature(coverage_attribute)]
#![feature(do_not_recommend)]
Expand Down
16 changes: 8 additions & 8 deletions core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1103,9 +1103,9 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
count: usize = count,
) => {
let zero_size = size == 0 || count == 0;
ub_checks::is_aligned_and_not_null(x, align, zero_size)
&& ub_checks::is_aligned_and_not_null(y, align, zero_size)
&& ub_checks::is_nonoverlapping(x, y, size, count)
ub_checks::maybe_is_aligned_and_not_null(x, align, zero_size)
&& ub_checks::maybe_is_aligned_and_not_null(y, align, zero_size)
&& ub_checks::maybe_is_nonoverlapping(x, y, size, count)
}
);

Expand Down Expand Up @@ -1216,7 +1216,7 @@ pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T {
addr: *const () = dst as *const (),
align: usize = align_of::<T>(),
is_zst: bool = T::IS_ZST,
) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
);
mem::replace(&mut *dst, src)
}
Expand Down Expand Up @@ -1369,7 +1369,7 @@ pub const unsafe fn read<T>(src: *const T) -> T {
addr: *const () = src as *const (),
align: usize = align_of::<T>(),
is_zst: bool = T::IS_ZST,
) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
);
crate::intrinsics::read_via_copy(src)
}
Expand Down Expand Up @@ -1573,7 +1573,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
addr: *mut () = dst as *mut (),
align: usize = align_of::<T>(),
is_zst: bool = T::IS_ZST,
) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
);
intrinsics::write_via_move(dst, src)
}
Expand Down Expand Up @@ -1745,7 +1745,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
addr: *const () = src as *const (),
align: usize = align_of::<T>(),
is_zst: bool = T::IS_ZST,
) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
);
intrinsics::volatile_load(src)
}
Expand Down Expand Up @@ -1825,7 +1825,7 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
addr: *mut () = dst as *mut (),
align: usize = align_of::<T>(),
is_zst: bool = T::IS_ZST,
) => ub_checks::is_aligned_and_not_null(addr, align, is_zst)
) => ub_checks::maybe_is_aligned_and_not_null(addr, align, is_zst)
);
intrinsics::volatile_store(dst, src);
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/slice/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
align: usize = align_of::<T>(),
len: usize = len,
) =>
ub_checks::is_aligned_and_not_null(data, align, false)
ub_checks::maybe_is_aligned_and_not_null(data, align, false)
&& ub_checks::is_valid_allocation_size(size, len)
);
&*ptr::slice_from_raw_parts(data, len)
Expand Down Expand Up @@ -186,7 +186,7 @@ pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a m
align: usize = align_of::<T>(),
len: usize = len,
) =>
ub_checks::is_aligned_and_not_null(data, align, false)
ub_checks::maybe_is_aligned_and_not_null(data, align, false)
&& ub_checks::is_valid_allocation_size(size, len)
);
&mut *ptr::slice_from_raw_parts_mut(data, len)
Expand Down
16 changes: 9 additions & 7 deletions core/src/ub_checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ macro_rules! assert_unsafe_precondition {
#[rustc_no_mir_inline]
#[inline]
#[rustc_nounwind]
#[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_ub_checks", issue = "none"))]
#[rustc_allow_const_fn_unstable(const_ub_checks)] // only for UB checks
const fn precondition_check($($name:$ty),*) {
if !$e {
::core::panicking::panic_nounwind(
Expand Down Expand Up @@ -116,12 +114,16 @@ pub(crate) const fn check_language_ub() -> bool {
/// for `assert_unsafe_precondition!` with `check_language_ub`, in which case the
/// check is anyway not executed in `const`.
#[inline]
#[rustc_const_unstable(feature = "const_ub_checks", issue = "none")]
pub(crate) const fn is_aligned_and_not_null(ptr: *const (), align: usize, is_zst: bool) -> bool {
#[rustc_allow_const_fn_unstable(const_eval_select)]
pub(crate) const fn maybe_is_aligned_and_not_null(
ptr: *const (),
align: usize,
is_zst: bool,
) -> bool {
// This is just for safety checks so we can const_eval_select.
const_eval_select!(
@capture { ptr: *const (), align: usize, is_zst: bool } -> bool:
if const #[rustc_const_unstable(feature = "const_ub_checks", issue = "none")] {
if const {
is_zst || !ptr.is_null()
} else {
ptr.is_aligned_to(align) && (is_zst || !ptr.is_null())
Expand All @@ -141,8 +143,8 @@ pub(crate) const fn is_valid_allocation_size(size: usize, len: usize) -> bool {
/// Note that in const-eval this function just returns `true` and therefore must
/// only be used with `assert_unsafe_precondition!`, similar to `is_aligned_and_not_null`.
#[inline]
#[rustc_const_unstable(feature = "const_ub_checks", issue = "none")]
pub(crate) const fn is_nonoverlapping(
#[rustc_allow_const_fn_unstable(const_eval_select)]
pub(crate) const fn maybe_is_nonoverlapping(
src: *const (),
dst: *const (),
size: usize,
Expand Down

0 comments on commit e4fb962

Please sign in to comment.