|  | 
| 448 | 448 | 
 | 
| 449 | 449 | use crate::cmp::Ordering; | 
| 450 | 450 | use crate::marker::FnPtr; | 
| 451 |  | -use crate::mem::{self, MaybeUninit}; | 
|  | 451 | +use crate::mem::{self, MaybeUninit, SizedTypeProperties}; | 
| 452 | 452 | use crate::{fmt, hash, intrinsics, ub_checks}; | 
| 453 | 453 | 
 | 
| 454 | 454 | mod alignment; | 
| @@ -1165,10 +1165,12 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) { | 
| 1165 | 1165 |             size: usize = size_of::<T>(), | 
| 1166 | 1166 |             align: usize = align_of::<T>(), | 
| 1167 | 1167 |             count: usize = count, | 
| 1168 |  | -        ) => | 
| 1169 |  | -        ub_checks::is_aligned_and_not_null(x, align) | 
| 1170 |  | -            && ub_checks::is_aligned_and_not_null(y, align) | 
| 1171 |  | -            && ub_checks::is_nonoverlapping(x, y, size, count) | 
|  | 1168 | +        ) => { | 
|  | 1169 | +            let zero_size = size == 0 || count == 0; | 
|  | 1170 | +            ub_checks::is_aligned_and_not_null(x, align, zero_size) | 
|  | 1171 | +                && ub_checks::is_aligned_and_not_null(y, align, zero_size) | 
|  | 1172 | +                && ub_checks::is_nonoverlapping(x, y, size, count) | 
|  | 1173 | +        } | 
| 1172 | 1174 |     ); | 
| 1173 | 1175 | 
 | 
| 1174 | 1176 |     // Split up the slice into small power-of-two-sized chunks that LLVM is able | 
| @@ -1277,7 +1279,8 @@ pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T { | 
| 1277 | 1279 |             ( | 
| 1278 | 1280 |                 addr: *const () = dst as *const (), | 
| 1279 | 1281 |                 align: usize = align_of::<T>(), | 
| 1280 |  | -            ) => ub_checks::is_aligned_and_not_null(addr, align) | 
|  | 1282 | +                is_zst: bool = T::IS_ZST, | 
|  | 1283 | +            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst) | 
| 1281 | 1284 |         ); | 
| 1282 | 1285 |         mem::replace(&mut *dst, src) | 
| 1283 | 1286 |     } | 
| @@ -1806,7 +1809,8 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T { | 
| 1806 | 1809 |             ( | 
| 1807 | 1810 |                 addr: *const () = src as *const (), | 
| 1808 | 1811 |                 align: usize = align_of::<T>(), | 
| 1809 |  | -            ) => ub_checks::is_aligned_and_not_null(addr, align) | 
|  | 1812 | +                is_zst: bool = T::IS_ZST, | 
|  | 1813 | +            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst) | 
| 1810 | 1814 |         ); | 
| 1811 | 1815 |         intrinsics::volatile_load(src) | 
| 1812 | 1816 |     } | 
| @@ -1885,7 +1889,8 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) { | 
| 1885 | 1889 |             ( | 
| 1886 | 1890 |                 addr: *mut () = dst as *mut (), | 
| 1887 | 1891 |                 align: usize = align_of::<T>(), | 
| 1888 |  | -            ) => ub_checks::is_aligned_and_not_null(addr, align) | 
|  | 1892 | +                is_zst: bool = T::IS_ZST, | 
|  | 1893 | +            ) => ub_checks::is_aligned_and_not_null(addr, align, is_zst) | 
| 1889 | 1894 |         ); | 
| 1890 | 1895 |         intrinsics::volatile_store(dst, src); | 
| 1891 | 1896 |     } | 
|  | 
0 commit comments