diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs index cef9cdcdd1..c367e7060f 100644 --- a/src/header/stdlib/mod.rs +++ b/src/header/stdlib/mod.rs @@ -2,6 +2,9 @@ //! //! See . +// TODO: set this for entire crate when possible +#![deny(unsafe_op_in_unsafe_fn)] + use core::{convert::TryFrom, intrinsics, iter, mem, ptr, slice}; use rand::{ Rng, SeedableRng, @@ -82,7 +85,7 @@ pub unsafe extern "C" fn a64l(s: *const c_char) -> c_long { // Handle up to 6 input characters (excl. null terminator) for i in 0..6 { - let digit_char = *s.offset(i); + let digit_char = unsafe { *s.offset(i) }; let digit_value = match digit_char { 0 => break, // Null terminator encountered @@ -124,7 +127,7 @@ static __stack_chk_guard: uintptr_t = 0xd048c37519fcadfe; #[unsafe(no_mangle)] unsafe extern "C" fn __stack_chk_fail() -> ! { - abort(); + unsafe { abort() }; } /// See . @@ -139,7 +142,7 @@ pub unsafe extern "C" fn aligned_alloc(alignment: size_t, size: size_t) -> *mut if size % alignment == 0 { /* The size-is-multiple-of-alignment requirement is the only * difference between aligned_alloc() and memalign(). */ - memalign(alignment, size) + unsafe { memalign(alignment, size) } } else { platform::ERRNO.set(EINVAL); ptr::null_mut() @@ -149,9 +152,9 @@ pub unsafe extern "C" fn aligned_alloc(alignment: size_t, size: size_t) -> *mut /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn at_quick_exit(func: Option) -> c_int { - for i in 0..AT_QUICK_EXIT_FUNCS.unsafe_ref().len() { - if AT_QUICK_EXIT_FUNCS.unsafe_ref()[i] == None { - AT_QUICK_EXIT_FUNCS.unsafe_mut()[i] = func; + for i in 0..unsafe { AT_QUICK_EXIT_FUNCS.unsafe_ref().len() } { + if unsafe { AT_QUICK_EXIT_FUNCS.unsafe_ref() }[i] == None { + (unsafe { AT_QUICK_EXIT_FUNCS.unsafe_mut() })[i] = func; return 0; } } @@ -162,9 +165,9 @@ pub unsafe extern "C" fn at_quick_exit(func: Option) -> c_int { /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn atexit(func: Option) -> c_int { - for i in 0..ATEXIT_FUNCS.unsafe_ref().len() { - if ATEXIT_FUNCS.unsafe_ref()[i] == None { - ATEXIT_FUNCS.unsafe_mut()[i] = func; + for i in 0..unsafe { ATEXIT_FUNCS.unsafe_ref().len() } { + if unsafe { ATEXIT_FUNCS.unsafe_ref() }[i] == None { + (unsafe { ATEXIT_FUNCS.unsafe_mut() })[i] = func; return 0; } } @@ -175,35 +178,35 @@ pub unsafe extern "C" fn atexit(func: Option) -> c_int { /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn atof(s: *const c_char) -> c_double { - strtod(s, ptr::null_mut()) + unsafe { strtod(s, ptr::null_mut()) } } macro_rules! dec_num_from_ascii { ($s:expr, $t:ty) => {{ let mut s = $s; // Iterate past whitespace - while ctype::isspace(*s as c_int) != 0 { - s = s.offset(1); + while ctype::isspace(unsafe { *s } as c_int) != 0 { + s = unsafe { s.offset(1) }; } // Find out if there is a - sign - let neg_sign = match *s { + let neg_sign = match unsafe { *s } { 0x2d => { - s = s.offset(1); + s = unsafe { s.offset(1) }; true } // '+' increment s and continue parsing 0x2b => { - s = s.offset(1); + s = unsafe { s.offset(1) }; false } _ => false, }; let mut n: $t = 0; - while ctype::isdigit(*s as c_int) != 0 { - n = 10 * n - (*s as $t - 0x30); - s = s.offset(1); + while ctype::isdigit(unsafe { *s } as c_int) != 0 { + n = 10 * n - (unsafe { *s } as $t - 0x30); + s = unsafe { s.offset(1) }; } if neg_sign { n } else { -n } @@ -213,7 +216,7 @@ macro_rules! dec_num_from_ascii { /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn atoi(s: *const c_char) -> c_int { - dec_num_from_ascii!(s, c_int) + unsafe { dec_num_from_ascii!(s, c_int) } } /// See . @@ -229,7 +232,7 @@ pub unsafe extern "C" fn atoll(s: *const c_char) -> c_longlong { } unsafe extern "C" fn void_cmp(a: *const c_void, b: *const c_void) -> c_int { - *(a as *const i32) - *(b as *const i32) as c_int + (unsafe { *(a as *const i32) }) - unsafe { *(b as *const i32) } as c_int } /// See . @@ -246,7 +249,7 @@ pub unsafe extern "C" fn bsearch( let cmp_fn = compar.unwrap_or(void_cmp); while len > 0 { let med = (start as size_t + (len >> 1) * width) as *const c_void; - let diff = cmp_fn(key, med); + let diff = unsafe { cmp_fn(key, med) }; if diff == 0 { return med as *mut c_void; } else if diff > 0 { @@ -266,9 +269,9 @@ pub unsafe extern "C" fn calloc(nelem: size_t, elsize: size_t) -> *mut c_void { Some(size) => { /* If allocation fails here, errno setting will be handled * by malloc() */ - let ptr = malloc(size); + let ptr = unsafe { malloc(size) }; if !ptr.is_null() { - ptr.write_bytes(0, size); + unsafe { ptr.write_bytes(0, size) }; } ptr } @@ -337,7 +340,8 @@ pub extern "C" fn ecvt( #[unsafe(no_mangle)] pub unsafe extern "C" fn erand48(xsubi: *mut c_ushort) -> c_double { let params = rand48::params(); - let xsubi_mut: &mut [c_ushort; 3] = slice::from_raw_parts_mut(xsubi, 3).try_into().unwrap(); + let xsubi_mut: &mut [c_ushort; 3] = + unsafe { slice::from_raw_parts_mut(xsubi, 3).try_into().unwrap() }; let new_xsubi_value = params.step(xsubi_mut.into()); *xsubi_mut = new_xsubi_value.into(); new_xsubi_value.get_f64() @@ -353,30 +357,30 @@ pub unsafe extern "C" fn exit(status: c_int) -> ! { fn _fini(); } - for i in (0..ATEXIT_FUNCS.unsafe_ref().len()).rev() { - if let Some(func) = ATEXIT_FUNCS.unsafe_ref()[i] { + for i in (0..unsafe { ATEXIT_FUNCS.unsafe_ref().len() }).rev() { + if let Some(func) = unsafe { ATEXIT_FUNCS.unsafe_ref() }[i] { (func)(); } } // Look for the neighbor functions in memory until the end - let mut f = &__fini_array_end as *const _; + let mut f = unsafe { &__fini_array_end } as *const _; #[allow(clippy::op_ref)] - while f > &__fini_array_start { - f = f.offset(-1); - (*f)(); + while f > unsafe { &__fini_array_start } { + f = unsafe { f.offset(-1) }; + (unsafe { *f })(); } #[cfg(not(target_arch = "riscv64"))] // risc-v uses arrays exclusively { - _fini(); + unsafe { _fini() }; } - ld_so::fini(); + unsafe { ld_so::fini() }; - crate::pthread::terminate_from_main_thread(); + unsafe { crate::pthread::terminate_from_main_thread() }; - flush_io_streams(); + unsafe { flush_io_streams() }; Sys::exit(status); } @@ -400,7 +404,7 @@ pub extern "C" fn fcvt( /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn free(ptr: *mut c_void) { - platform::free(ptr); + unsafe { platform::free(ptr) }; } /// See . @@ -418,26 +422,26 @@ unsafe fn find_env(search: *const c_char) -> Option<(usize, *mut c_char)> { for (i, mut item) in platform::environ_iter().enumerate() { let mut search = search; loop { - let end_of_query = *search == 0 || *search == b'=' as c_char; - if *item == 0 { + let end_of_query = unsafe { *search } == 0 || unsafe { *search } == b'=' as c_char; + if unsafe { *item } == 0 { //TODO: environ has an item without value, is this a problem? break; } - if *item == b'=' as c_char || end_of_query { - if *item == b'=' as c_char && end_of_query { + if unsafe { *item } == b'=' as c_char || end_of_query { + if unsafe { *item } == b'=' as c_char && end_of_query { // Both keys env here - return Some((i, item.add(1))); + return Some((i, unsafe { item.add(1) })); } else { break; } } - if *item != *search { + if unsafe { *item } != unsafe { *search } { break; } - item = item.add(1); - search = search.add(1); + item = unsafe { item.add(1) }; + search = unsafe { search.add(1) }; } } @@ -447,7 +451,9 @@ unsafe fn find_env(search: *const c_char) -> Option<(usize, *mut c_char)> { /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn getenv(name: *const c_char) -> *mut c_char { - find_env(name).map(|val| val.1).unwrap_or(ptr::null_mut()) + unsafe { find_env(name) } + .map(|val| val.1) + .unwrap_or(ptr::null_mut()) } /// See . @@ -457,48 +463,52 @@ pub unsafe extern "C" fn getsubopt( keylistp: *const *mut c_char, valuep: *mut *mut c_char, ) -> c_int { - if optionp.is_null() || (*optionp).is_null() || keylistp.is_null() || valuep.is_null() { + if optionp.is_null() + || (unsafe { *optionp }).is_null() + || keylistp.is_null() + || valuep.is_null() + { return -1; } - let start = *optionp; + let start = unsafe { *optionp }; let mut cursor = start; let mut found_comma = false; - while *cursor != 0 { - if *cursor == b',' as c_char { - *cursor = 0; - *optionp = cursor.add(1); + while unsafe { *cursor } != 0 { + if unsafe { *cursor } == b',' as c_char { + unsafe { *cursor = 0 }; + unsafe { *optionp = cursor.add(1) }; found_comma = true; break; } - cursor = cursor.add(1); + cursor = unsafe { cursor.add(1) }; } if !found_comma { - *optionp = cursor; + unsafe { *optionp = cursor }; } let mut i = 0; - while !(*keylistp.add(i)).is_null() { - let token = *keylistp.add(i); - let token_len = strlen(token); + while !(unsafe { *keylistp.add(i) }).is_null() { + let token = unsafe { *keylistp.add(i) }; + let token_len = unsafe { strlen(token) }; - if strncmp(start, token, token_len) == 0 { - let suffix_char = *start.add(token_len); + if unsafe { strncmp(start, token, token_len) } == 0 { + let suffix_char = unsafe { *start.add(token_len) }; if suffix_char == b'=' as c_char { - *valuep = start.add(token_len + 1); + unsafe { *valuep = start.add(token_len + 1) }; return i as c_int; } else if suffix_char == 0 { - *valuep = ptr::null_mut(); + unsafe { *valuep = ptr::null_mut() }; return i as c_int; } } i += 1; } - *valuep = start; + unsafe { *valuep = start }; -1 } @@ -517,7 +527,7 @@ pub unsafe extern "C" fn initstate(seed: c_uint, state: *mut c_char, size: size_ ptr::null_mut() } else { let mut random_state = random::state_lock(); - let old_state = random_state.save(); + let old_state = unsafe { random_state.save() }; random_state.n = match size { 0..=7 => unreachable!(), // ensured above 8..=31 => 0, @@ -527,9 +537,9 @@ pub unsafe extern "C" fn initstate(seed: c_uint, state: *mut c_char, size: size_ _ => 63, }; - random_state.x_ptr = (state.cast::<[u8; 4]>()).offset(1); - random_state.seed(seed); - random_state.save(); + random_state.x_ptr = unsafe { (state.cast::<[u8; 4]>()).offset(1) }; + unsafe { random_state.seed(seed) }; + unsafe { random_state.save() }; old_state.cast::<_>() } @@ -547,7 +557,9 @@ pub unsafe extern "C" fn initstate(seed: c_uint, state: *mut c_char, size: size_ #[unsafe(no_mangle)] pub unsafe extern "C" fn jrand48(xsubi: *mut c_ushort) -> c_long { let params = rand48::params(); - let xsubi_mut: &mut [c_ushort; 3] = slice::from_raw_parts_mut(xsubi, 3).try_into().unwrap(); + let xsubi_mut: &mut [c_ushort; 3] = unsafe { slice::from_raw_parts_mut(xsubi, 3) } + .try_into() + .unwrap(); let new_xsubi_value = params.step(xsubi_mut.into()); *xsubi_mut = new_xsubi_value.into(); new_xsubi_value.get_i32() @@ -567,13 +579,13 @@ pub unsafe extern "C" fn l64a(value: c_long) -> *mut c_char { let num_output_digits = usize::try_from(6 - (value_as_i32.leading_zeros() + 4) / 6).unwrap(); // Reset buffer (and have null terminator in place for any result) - L64A_BUFFER.unsafe_set([0; 7]); + unsafe { L64A_BUFFER.unsafe_set([0; 7]) }; for i in 0..num_output_digits { // Conversion to c_char always succeeds for the range 0..=63 let digit_value = c_char::try_from((value_as_i32 >> 6 * i) & 63).unwrap(); - L64A_BUFFER.unsafe_mut()[i] = match digit_value { + (unsafe { L64A_BUFFER.unsafe_mut() })[i] = match digit_value { 0..=11 => { // ./0123456789 for values 0 to 11. b'.' == 46 46 + digit_value @@ -590,7 +602,7 @@ pub unsafe extern "C" fn l64a(value: c_long) -> *mut c_char { }; } - L64A_BUFFER.unsafe_mut().as_mut_ptr() + unsafe { L64A_BUFFER.unsafe_mut().as_mut_ptr() } } /// See . @@ -613,7 +625,7 @@ pub unsafe extern "C" fn lcong48(param: *mut c_ushort) { let mut xsubi = rand48::xsubi_lock(); let mut params = rand48::params_mut(); - let param_slice = slice::from_raw_parts(param, 7); + let param_slice = unsafe { slice::from_raw_parts(param, 7) }; let xsubi_ref: &[c_ushort; 3] = param_slice[0..3].try_into().unwrap(); let a_ref: &[c_ushort; 3] = param_slice[3..6].try_into().unwrap(); @@ -677,7 +689,7 @@ pub extern "C" fn lrand48() -> c_long { /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn malloc(size: size_t) -> *mut c_void { - let ptr = platform::alloc(size); + let ptr = unsafe { platform::alloc(size) }; if ptr.is_null() { platform::ERRNO.set(ENOMEM); } @@ -689,7 +701,7 @@ pub unsafe extern "C" fn malloc(size: size_t) -> *mut c_void { #[unsafe(no_mangle)] pub unsafe extern "C" fn memalign(alignment: size_t, size: size_t) -> *mut c_void { if alignment.is_power_of_two() { - let ptr = platform::alloc_align(size, alignment); + let ptr = unsafe { platform::alloc_align(size, alignment) }; if ptr.is_null() { platform::ERRNO.set(ENOMEM); } @@ -705,7 +717,7 @@ pub unsafe extern "C" fn memalign(alignment: size_t, size: size_t) -> *mut c_voi pub unsafe extern "C" fn mblen(s: *const c_char, n: size_t) -> c_int { let mut wc: wchar_t = 0; let mut state: mbstate_t = mbstate_t {}; - let result: usize = mbrtowc(&mut wc, s, n, &mut state); + let result: usize = unsafe { mbrtowc(&mut wc, s, n, &mut state) }; if result == -1isize as usize { return -1; @@ -721,14 +733,14 @@ pub unsafe extern "C" fn mblen(s: *const c_char, n: size_t) -> c_int { #[unsafe(no_mangle)] pub unsafe extern "C" fn mbstowcs(pwcs: *mut wchar_t, mut s: *const c_char, n: size_t) -> size_t { let mut state: mbstate_t = mbstate_t {}; - mbsrtowcs(pwcs, &mut s, n, &mut state) + unsafe { mbsrtowcs(pwcs, &mut s, n, &mut state) } } /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn mbtowc(pwc: *mut wchar_t, s: *const c_char, n: size_t) -> c_int { let mut state: mbstate_t = mbstate_t {}; - mbrtowc(pwc, s, n, &mut state) as c_int + (unsafe { mbrtowc(pwc, s, n, &mut state) }) as c_int } fn inner_mktemp(name: *mut c_char, suffix_len: c_int, mut attempt: F) -> Option @@ -786,7 +798,7 @@ fn get_nstime() -> u64 { #[unsafe(no_mangle)] pub unsafe extern "C" fn mkdtemp(name: *mut c_char) -> *mut c_char { inner_mktemp(name, 0, || { - let name_c = CStr::from_ptr(name); + let name_c = unsafe { CStr::from_ptr(name) }; match Sys::mkdir(name_c, 0o700) { Ok(()) => Some(name), Err(_) => None, @@ -798,7 +810,7 @@ pub unsafe extern "C" fn mkdtemp(name: *mut c_char) -> *mut c_char { /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn mkostemp(name: *mut c_char, flags: c_int) -> c_int { - mkostemps(name, 0, flags) + unsafe { mkostemps(name, 0, flags) } } /// Non-POSIX, see . @@ -814,7 +826,7 @@ pub unsafe extern "C" fn mkostemps( flags |= O_RDWR | O_CREAT | O_EXCL; inner_mktemp(name, suffix_len, || { - let name = CStr::from_ptr(name); + let name = unsafe { CStr::from_ptr(name) }; let fd = Sys::open(name, flags, 0o600).or_minus_one_errno(); if fd >= 0 { Some(fd) } else { None } @@ -825,13 +837,13 @@ pub unsafe extern "C" fn mkostemps( /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn mkstemp(name: *mut c_char) -> c_int { - mkostemps(name, 0, 0) + unsafe { mkostemps(name, 0, 0) } } /// Non-POSIX, see . #[unsafe(no_mangle)] pub unsafe extern "C" fn mkstemps(name: *mut c_char, suffix_len: c_int) -> c_int { - mkostemps(name, suffix_len, 0) + unsafe { mkostemps(name, suffix_len, 0) } } /// See . @@ -843,7 +855,7 @@ pub unsafe extern "C" fn mkstemps(name: *mut c_char, suffix_len: c_int) -> c_int #[unsafe(no_mangle)] pub unsafe extern "C" fn mktemp(name: *mut c_char) -> *mut c_char { if inner_mktemp(name, 0, || { - let name = CStr::from_ptr(name); + let name = unsafe { CStr::from_ptr(name) }; if Sys::access(name, 0) == Err(Errno(ENOENT)) { Some(()) } else { @@ -852,7 +864,7 @@ pub unsafe extern "C" fn mktemp(name: *mut c_char) -> *mut c_char { }) .is_none() { - *name = 0; + unsafe { *name = 0 }; } name } @@ -882,7 +894,9 @@ pub extern "C" fn mrand48() -> c_long { #[unsafe(no_mangle)] pub unsafe extern "C" fn nrand48(xsubi: *mut c_ushort) -> c_long { let params = rand48::params(); - let xsubi_mut: &mut [c_ushort; 3] = slice::from_raw_parts_mut(xsubi, 3).try_into().unwrap(); + let xsubi_mut: &mut [c_ushort; 3] = unsafe { slice::from_raw_parts_mut(xsubi, 3) } + .try_into() + .unwrap(); let new_xsubi_value = params.step(xsubi_mut.into()); *xsubi_mut = new_xsubi_value.into(); new_xsubi_value.get_u31() @@ -898,11 +912,11 @@ pub unsafe extern "C" fn posix_memalign( const VOID_PTR_SIZE: usize = mem::size_of::<*mut c_void>(); if alignment % VOID_PTR_SIZE == 0 && alignment.is_power_of_two() { - let ptr = platform::alloc_align(size, alignment); - *memptr = ptr; + let ptr = unsafe { platform::alloc_align(size, alignment) }; + unsafe { *memptr = ptr }; if ptr.is_null() { ENOMEM } else { 0 } } else { - *memptr = ptr::null_mut(); + unsafe { *memptr = ptr::null_mut() }; EINVAL } } @@ -914,7 +928,7 @@ pub unsafe extern "C" fn posix_openpt(flags: c_int) -> c_int { let r = open((b"/scheme/pty\0" as *const u8).cast(), O_CREAT); #[cfg(target_os = "linux")] - let r = open((b"/dev/ptmx\0" as *const u8).cast(), flags); + let r = unsafe { open((b"/dev/ptmx\0" as *const u8).cast(), flags) }; if r < 0 && platform::ERRNO.get() == ENOSPC { platform::ERRNO.set(EAGAIN); @@ -928,7 +942,7 @@ pub unsafe extern "C" fn posix_openpt(flags: c_int) -> c_int { pub unsafe extern "C" fn ptsname(fd: c_int) -> *mut c_char { const PTS_BUFFER_LEN: usize = 9 + mem::size_of::() * 3 + 1; static mut PTS_BUFFER: [c_char; PTS_BUFFER_LEN] = [0; PTS_BUFFER_LEN]; - if ptsname_r(fd, &raw mut PTS_BUFFER as *mut _, PTS_BUFFER_LEN) != 0 { + if unsafe { ptsname_r(fd, &raw mut PTS_BUFFER as *mut _, PTS_BUFFER_LEN) } != 0 { ptr::null_mut() } else { &raw mut PTS_BUFFER as *mut _ @@ -942,7 +956,7 @@ pub unsafe extern "C" fn ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t) platform::ERRNO.set(EINVAL); EINVAL } else { - __ptsname_r(fd, buf, buflen) + unsafe { __ptsname_r(fd, buf, buflen) } } } @@ -975,7 +989,7 @@ unsafe fn __ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t) -> c_int { let mut pty = 0; let err = platform::ERRNO.get(); - if ioctl(fd, TIOCGPTN, &mut pty as *mut _ as *mut c_void) == 0 { + if unsafe { ioctl(fd, TIOCGPTN, &mut pty as *mut _ as *mut c_void) } == 0 { let name = format!("/dev/pts/{}", pty); let len = name.len(); if len > buflen { @@ -985,7 +999,7 @@ unsafe fn __ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t) -> c_int { // we have checked the string will fit in the buffer // so can use strcpy safely let s = name.as_ptr().cast(); - ptr::copy_nonoverlapping(s, buf, len); + unsafe { ptr::copy_nonoverlapping(s, buf, len) }; platform::ERRNO.set(err); 0 } @@ -997,23 +1011,23 @@ unsafe fn __ptsname_r(fd: c_int, buf: *mut c_char, buflen: size_t) -> c_int { unsafe fn put_new_env(insert: *mut c_char) { // XXX: Another problem is that `environ` can be set to any pointer, which means there is a // chance of a memory leak. But we can check if it was the same as before, like musl does. - if platform::environ == platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() { + if unsafe { platform::environ } == unsafe { platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() } { { - let mut our_environ = &mut *platform::OUR_ENVIRON.as_mut_ptr(); + let mut our_environ = unsafe { &mut *platform::OUR_ENVIRON.as_mut_ptr() }; *our_environ.last_mut().unwrap() = insert; our_environ.push(core::ptr::null_mut()); } // Likely a no-op but is needed due to Stacked Borrows. - platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr(); + unsafe { platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() }; } else { { - let mut our_environ = &mut *platform::OUR_ENVIRON.as_mut_ptr(); + let mut our_environ = unsafe { &mut *platform::OUR_ENVIRON.as_mut_ptr() }; our_environ.clear(); our_environ.extend(platform::environ_iter()); our_environ.push(insert); our_environ.push(core::ptr::null_mut()); } - platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr(); + unsafe { platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() }; } } @@ -1021,13 +1035,13 @@ unsafe fn put_new_env(insert: *mut c_char) { #[unsafe(no_mangle)] pub unsafe extern "C" fn putenv(insert: *mut c_char) -> c_int { assert_ne!(insert, ptr::null_mut(), "putenv(NULL)"); - if let Some((i, _)) = find_env(insert) { + if let Some((i, _)) = unsafe { find_env(insert) } { // XXX: The POSIX manual states that environment variables can be *set* via the `environ` // global variable. While we can check if a pointer belongs to our allocator, or check // `environ` against a vector which we control, it is likely not worth the effort. - platform::environ.add(i).write(insert); + unsafe { platform::environ.add(i).write(insert) }; } else { - put_new_env(insert); + unsafe { put_new_env(insert) }; } 0 } @@ -1045,7 +1059,7 @@ pub unsafe extern "C" fn qsort( if nel > 0 { // XXX: maybe try to do mergesort/timsort first and fallback to introsort if memory // allocation fails? not sure what is ideal - sort::introsort(base as *mut c_char, nel, width, comp); + unsafe { sort::introsort(base as *mut c_char, nel, width, comp) }; } } } @@ -1065,8 +1079,8 @@ pub unsafe extern "C" fn qsort_r( /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn quick_exit(status: c_int) -> ! { - for i in (0..AT_QUICK_EXIT_FUNCS.unsafe_ref().len()).rev() { - if let Some(func) = AT_QUICK_EXIT_FUNCS.unsafe_ref()[i] { + for i in (0..unsafe { AT_QUICK_EXIT_FUNCS.unsafe_ref() }.len()).rev() { + if let Some(func) = unsafe { AT_QUICK_EXIT_FUNCS.unsafe_ref() }[i] { (func)(); } } @@ -1077,13 +1091,15 @@ pub unsafe extern "C" fn quick_exit(status: c_int) -> ! { /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn rand() -> c_int { - match RNG { - Some(ref mut rng) => rng_sampler().sample(rng), - None => { - let mut rng = XorShiftRng::from_seed([1; 16]); - let ret = rng_sampler().sample(&mut rng); - RNG = Some(rng); - ret + unsafe { + match RNG { + Some(ref mut rng) => rng_sampler().sample(rng), + None => { + let mut rng = XorShiftRng::from_seed([1; 16]); + let ret = rng_sampler().sample(&mut rng); + unsafe { RNG = Some(rng) }; + ret + } } } } @@ -1099,12 +1115,12 @@ pub unsafe extern "C" fn rand_r(seed: *mut c_uint) -> c_int { errno::EINVAL } else { // set the type explicitly so this will fail if the array size for XorShiftRng changes - let seed_arr: [u8; 16] = mem::transmute([*seed; 16 / mem::size_of::()]); + let seed_arr: [u8; 16] = unsafe { mem::transmute([*seed; 16 / mem::size_of::()]) }; let mut rng = XorShiftRng::from_seed(seed_arr); let ret = rng_sampler().sample(&mut rng); - *seed = ret as _; + unsafe { *seed = ret as _ }; ret } @@ -1118,19 +1134,21 @@ pub unsafe extern "C" fn random() -> c_long { let k: u32; - random_state.ensure_x_ptr_init(); + unsafe { random_state.ensure_x_ptr_init() }; if random_state.n == 0 { - let x_old = u32::from_ne_bytes(*random_state.x_ptr); + let x_old = u32::from_ne_bytes(unsafe { *random_state.x_ptr }); let x_new = random::lcg31_step(x_old); - *random_state.x_ptr = x_new.to_ne_bytes(); + unsafe { *random_state.x_ptr = x_new.to_ne_bytes() }; k = x_new; } else { // The non-u32-aligned way of saying x[i] += x[j]... - let x_i_old = u32::from_ne_bytes(*random_state.x_ptr.add(usize::from(random_state.i))); - let x_j = u32::from_ne_bytes(*random_state.x_ptr.add(usize::from(random_state.j))); + let x_i_old = + u32::from_ne_bytes(unsafe { *random_state.x_ptr.add(usize::from(random_state.i)) }); + let x_j = + u32::from_ne_bytes(unsafe { *random_state.x_ptr.add(usize::from(random_state.j)) }); let x_i_new = x_i_old.wrapping_add(x_j); - *random_state.x_ptr.add(usize::from(random_state.i)) = x_i_new.to_ne_bytes(); + unsafe { *random_state.x_ptr.add(usize::from(random_state.i)) = x_i_new.to_ne_bytes() }; k = x_i_new >> 1; @@ -1153,7 +1171,7 @@ pub unsafe extern "C" fn random() -> c_long { /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void { - let new_ptr = platform::realloc(ptr, size); + let new_ptr = unsafe { platform::realloc(ptr, size) }; if new_ptr.is_null() { platform::ERRNO.set(ENOMEM); } @@ -1165,7 +1183,7 @@ pub unsafe extern "C" fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void pub unsafe extern "C" fn reallocarray(ptr: *mut c_void, m: size_t, n: size_t) -> *mut c_void { //Handle possible integer overflow in size calculation match m.checked_mul(n) { - Some(size) => realloc(ptr, size), + Some(size) => unsafe { realloc(ptr, size) }, None => { // For overflowing multiplication, we have to set errno here platform::ERRNO.set(ENOMEM); @@ -1178,14 +1196,14 @@ pub unsafe extern "C" fn reallocarray(ptr: *mut c_void, m: size_t, n: size_t) -> #[unsafe(no_mangle)] pub unsafe extern "C" fn realpath(pathname: *const c_char, resolved: *mut c_char) -> *mut c_char { let ptr = if resolved.is_null() { - malloc(limits::PATH_MAX) as *mut c_char + (unsafe { malloc(limits::PATH_MAX) }) as *mut c_char } else { resolved }; - let out = slice::from_raw_parts_mut(ptr as *mut u8, limits::PATH_MAX); + let out = unsafe { slice::from_raw_parts_mut(ptr as *mut u8, limits::PATH_MAX) }; { - let file = match File::open(CStr::from_ptr(pathname), O_PATH | O_CLOEXEC) { + let file = match File::open(unsafe { CStr::from_ptr(pathname) }, O_PATH | O_CLOEXEC) { Ok(file) => file, Err(_) => return ptr::null_mut(), }; @@ -1228,9 +1246,11 @@ pub unsafe extern "C" fn seed48(seed16v: *mut c_ushort) -> *mut c_ushort { let mut params = rand48::params_mut(); let mut xsubi = rand48::xsubi_lock(); - let seed16v_ref: &[c_ushort; 3] = slice::from_raw_parts(seed16v, 3).try_into().unwrap(); + let seed16v_ref: &[c_ushort; 3] = unsafe { slice::from_raw_parts(seed16v, 3) } + .try_into() + .unwrap(); - BUFFER = (*xsubi).into(); + unsafe { BUFFER = (*xsubi).into() }; *xsubi = seed16v_ref.into(); params.reset(); &raw mut BUFFER as *mut _ @@ -1243,10 +1263,10 @@ unsafe fn copy_kv( key_len: usize, value_len: usize, ) { - core::ptr::copy_nonoverlapping(key, existing, key_len); - core::ptr::write(existing.add(key_len), b'=' as c_char); - core::ptr::copy_nonoverlapping(value, existing.add(key_len + 1), value_len); - core::ptr::write(existing.add(key_len + 1 + value_len), 0); + unsafe { core::ptr::copy_nonoverlapping(key, existing, key_len) }; + unsafe { core::ptr::write(existing.add(key_len), b'=' as c_char) }; + unsafe { core::ptr::copy_nonoverlapping(value, existing.add(key_len + 1), value_len) }; + unsafe { core::ptr::write(existing.add(key_len + 1 + value_len), 0) }; } /// See . @@ -1256,32 +1276,34 @@ pub unsafe extern "C" fn setenv( value: *const c_char, overwrite: c_int, ) -> c_int { - let key_len = strlen(key); - let value_len = strlen(value); + let key_len = unsafe { strlen(key) }; + let value_len = unsafe { strlen(value) }; - if let Some((i, existing)) = find_env(key) { + if let Some((i, existing)) = unsafe { find_env(key) } { if overwrite == 0 { return 0; } - let existing_len = strlen(existing); + let existing_len = unsafe { strlen(existing) }; if existing_len >= value_len { // Reuse existing element's allocation - core::ptr::copy_nonoverlapping(value, existing, value_len); + unsafe { core::ptr::copy_nonoverlapping(value, existing, value_len) }; //TODO: fill to end with zeroes - core::ptr::write(existing.add(value_len), 0); + unsafe { core::ptr::write(existing.add(value_len), 0) }; } else { // Reuse platform::environ slot, but allocate a new pointer. - let ptr = platform::alloc(key_len as usize + 1 + value_len as usize + 1) as *mut c_char; - copy_kv(ptr, key, value, key_len, value_len); - platform::environ.add(i).write(ptr); + let ptr = unsafe { platform::alloc(key_len as usize + 1 + value_len as usize + 1) } + as *mut c_char; + unsafe { copy_kv(ptr, key, value, key_len, value_len) }; + unsafe { platform::environ.add(i).write(ptr) }; } } else { // Expand platform::environ and allocate a new pointer. - let ptr = platform::alloc(key_len as usize + 1 + value_len as usize + 1) as *mut c_char; - copy_kv(ptr, key, value, key_len, value_len); - put_new_env(ptr); + let ptr = unsafe { platform::alloc(key_len as usize + 1 + value_len as usize + 1) } + as *mut c_char; + unsafe { copy_kv(ptr, key, value, key_len, value_len) }; + unsafe { put_new_env(ptr) }; } //platform::free(platform::inner_environ[index] as *mut c_void); @@ -1306,8 +1328,8 @@ pub unsafe extern "C" fn setkey(key: *const c_char) { pub unsafe extern "C" fn setstate(state: *mut c_char) -> *mut c_char { let mut random_state = random::state_lock(); - let old_state = random_state.save(); - random_state.load(state.cast::<_>()); + let old_state = unsafe { random_state.save() }; + unsafe { random_state.load(state.cast::<_>()) }; old_state.cast::<_>() } @@ -1315,7 +1337,7 @@ pub unsafe extern "C" fn setstate(state: *mut c_char) -> *mut c_char { /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn srand(seed: c_uint) { - RNG = Some(XorShiftRng::from_seed([seed as u8; 16])); + unsafe { RNG = Some(XorShiftRng::from_seed([seed as u8; 16])) }; } /// See . @@ -1343,7 +1365,7 @@ pub extern "C" fn srand48(seedval: c_long) { pub unsafe extern "C" fn srandom(seed: c_uint) { let mut random_state = random::state_lock(); - random_state.seed(seed); + unsafe { random_state.seed(seed) }; } pub fn is_positive(ch: c_char) -> Option<(bool, isize)> { @@ -1356,11 +1378,11 @@ pub fn is_positive(ch: c_char) -> Option<(bool, isize)> { } pub unsafe fn detect_base(s: *const c_char) -> Option<(c_int, isize)> { - let first = *s as u8; + let first = unsafe { *s } as u8; match first { 0 => None, b'0' => { - let second = *s.offset(1) as u8; + let second = unsafe { *s.offset(1) } as u8; if second == b'X' || second == b'x' { Some((16, 2)) } else if second >= b'0' && second <= b'7' { @@ -1375,8 +1397,8 @@ pub unsafe fn detect_base(s: *const c_char) -> Option<(c_int, isize)> { } pub unsafe fn convert_octal(s: *const c_char) -> Option<(c_ulong, isize, bool)> { - if *s != 0 && *s == b'0' as c_char { - if let Some((val, idx, overflow)) = convert_integer(s.offset(1), 8) { + if unsafe { *s } != 0 && unsafe { *s } == b'0' as c_char { + if let Some((val, idx, overflow)) = unsafe { convert_integer(s.offset(1), 8) } { Some((val, idx + 1, overflow)) } else { // in case the prefix is not actually a prefix @@ -1388,12 +1410,15 @@ pub unsafe fn convert_octal(s: *const c_char) -> Option<(c_ulong, isize, bool)> } pub unsafe fn convert_hex(s: *const c_char) -> Option<(c_ulong, isize, bool)> { - if (*s != 0 && *s == b'0' as c_char) - && (*s.offset(1) != 0 && (*s.offset(1) == b'x' as c_char || *s.offset(1) == b'X' as c_char)) + if (unsafe { *s } != 0 && unsafe { *s } == b'0' as c_char) + && (unsafe { *s.offset(1) } != 0 + && (unsafe { *s.offset(1) } == b'x' as c_char + || unsafe { *s.offset(1) } == b'X' as c_char)) { - convert_integer(s.offset(2), 16).map(|(val, idx, overflow)| (val, idx + 2, overflow)) + unsafe { convert_integer(s.offset(2), 16) } + .map(|(val, idx, overflow)| (val, idx + 2, overflow)) } else { - convert_integer(s, 16).map(|(val, idx, overflow)| (val, idx, overflow)) + unsafe { convert_integer(s, 16) }.map(|(val, idx, overflow)| (val, idx, overflow)) } } @@ -1427,7 +1452,7 @@ pub unsafe fn convert_integer(s: *const c_char, base: c_int) -> Option<(c_ulong, // `-1 as usize` is usize::MAX // `-1 as u8 as usize` is u8::MAX // It extends by the sign bit unless we cast it to unsigned first. - let val = LOOKUP_TABLE[*s.offset(idx) as u8 as usize]; + let val = LOOKUP_TABLE[unsafe { *s.offset(idx) } as u8 as usize]; if val == -1 || val as c_int >= base { break; } else { @@ -1543,7 +1568,7 @@ pub unsafe extern "C" fn system(command: *const c_char) -> c_int { // handle shell detection on command == NULL if command.is_null() { - let status = system("exit 0\0".as_ptr() as *const c_char); + let status = unsafe { system("exit 0\0".as_ptr() as *const c_char) }; if status == 0 { return 1; } else { @@ -1551,7 +1576,7 @@ pub unsafe extern "C" fn system(command: *const c_char) -> c_int { } } - let child_pid = unistd::fork(); + let child_pid = unsafe { unistd::fork() }; if child_pid == 0 { let command_nonnull = command as *const u8; @@ -1564,9 +1589,9 @@ pub unsafe extern "C" fn system(command: *const c_char) -> c_int { ptr::null(), ]; - unistd::execv(shell as *const c_char, args.as_ptr() as *const *mut c_char); + unsafe { unistd::execv(shell as *const c_char, args.as_ptr() as *const *mut c_char) }; - exit(127); + unsafe { exit(127) }; unreachable!(); } else if child_pid > 0 { @@ -1597,26 +1622,28 @@ pub extern "C" fn ttyslot() -> c_int { #[unsafe(no_mangle)] pub unsafe extern "C" fn unlockpt(fildes: c_int) -> c_int { let mut u: c_int = 0; - ioctl(fildes, TIOCSPTLCK, &mut u as *mut i32 as *mut c_void) + unsafe { ioctl(fildes, TIOCSPTLCK, &mut u as *mut i32 as *mut c_void) } } /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn unsetenv(key: *const c_char) -> c_int { - if let Some((i, _)) = find_env(key) { - if platform::environ == platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() { + if let Some((i, _)) = unsafe { find_env(key) } { + if unsafe { platform::environ } + == unsafe { platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() } + { // No need to worry about updating the pointer, this does not // reallocate in any way. And the final null is already shifted back. { - let mut our_environ = &mut *platform::OUR_ENVIRON.as_mut_ptr(); + let mut our_environ = unsafe { &mut *platform::OUR_ENVIRON.as_mut_ptr() }; our_environ.remove(i); } // My UB paranoia. - platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr(); + unsafe { platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() }; } else { { - let mut our_environ = &mut *platform::OUR_ENVIRON.as_mut_ptr(); + let mut our_environ = unsafe { &mut *platform::OUR_ENVIRON.as_mut_ptr() }; our_environ.clear(); our_environ.extend( platform::environ_iter() @@ -1626,7 +1653,7 @@ pub unsafe extern "C" fn unsetenv(key: *const c_char) -> c_int { ); our_environ.push(core::ptr::null_mut()); } - platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr(); + unsafe { platform::environ = platform::OUR_ENVIRON.unsafe_mut().as_mut_ptr() }; } } 0 @@ -1642,11 +1669,11 @@ pub unsafe extern "C" fn unsetenv(key: *const c_char) -> c_int { pub unsafe extern "C" fn valloc(size: size_t) -> *mut c_void { /* sysconf(_SC_PAGESIZE) is a c_long and may in principle not * convert correctly to a size_t. */ - match size_t::try_from(sysconf(_SC_PAGESIZE)) { + match size_t::try_from(unsafe { sysconf(_SC_PAGESIZE) }) { Ok(page_size) => { /* valloc() is not supposed to be able to set errno to * EINVAL, hence no call to memalign(). */ - let ptr = platform::alloc_align(size, page_size); + let ptr = unsafe { platform::alloc_align(size, page_size) }; if ptr.is_null() { platform::ERRNO.set(ENOMEM); } @@ -1663,14 +1690,14 @@ pub unsafe extern "C" fn valloc(size: size_t) -> *mut c_void { #[unsafe(no_mangle)] pub unsafe extern "C" fn wcstombs(s: *mut c_char, mut pwcs: *const wchar_t, n: size_t) -> size_t { let mut state: mbstate_t = mbstate_t {}; - wcsrtombs(s, &mut pwcs, n, &mut state) + unsafe { wcsrtombs(s, &mut pwcs, n, &mut state) } } /// See . #[unsafe(no_mangle)] pub unsafe extern "C" fn wctomb(s: *mut c_char, wc: wchar_t) -> c_int { let mut state: mbstate_t = mbstate_t {}; - let result: usize = wcrtomb(s, wc, &mut state); + let result: usize = unsafe { wcrtomb(s, wc, &mut state) }; if result == -1isize as usize { return -1; diff --git a/src/header/stdlib/random.rs b/src/header/stdlib/random.rs index 16733f0add..14ec843be1 100644 --- a/src/header/stdlib/random.rs +++ b/src/header/stdlib/random.rs @@ -1,6 +1,9 @@ //! Helper functions for random() and friends, see https://pubs.opengroup.org/onlinepubs/7908799/xsh/initstate.html // Ported from musl's implementation (src/prng/random.c) +// TODO: set this for entire crate when possible +#![deny(unsafe_op_in_unsafe_fn)] + use crate::{ platform::types::*, sync::{Mutex, MutexGuard}, @@ -34,23 +37,23 @@ impl State { /// To be called in any function that may read from X_PTR pub unsafe fn ensure_x_ptr_init(&mut self) { if self.x_ptr.is_null() { - let x_u32_ptr: *mut u32 = DEFAULT_X.get().cast::().add(1); + let x_u32_ptr: *mut u32 = unsafe { DEFAULT_X.get().cast::().add(1) }; self.x_ptr = x_u32_ptr.cast::<[u8; 4]>(); } } pub unsafe fn save(&mut self) -> *mut [u8; 4] { - self.ensure_x_ptr_init(); + unsafe { self.ensure_x_ptr_init() }; let stash_value: u32 = (u32::from(self.n) << 16) | (u32::from(self.i) << 8) | u32::from(self.j); - *self.x_ptr.offset(-1) = stash_value.to_ne_bytes(); - self.x_ptr.offset(-1) + unsafe { *self.x_ptr.offset(-1) = stash_value.to_ne_bytes() }; + unsafe { self.x_ptr.offset(-1) } } pub unsafe fn load(&mut self, state_ptr: *mut [u8; 4]) { - let stash_value = u32::from_ne_bytes(*state_ptr); - self.x_ptr = state_ptr.offset(1); + let stash_value = u32::from_ne_bytes(unsafe { *state_ptr }); + self.x_ptr = unsafe { state_ptr.offset(1) }; /* This calculation of n does not have a bit mask in the musl * original, in principle resulting in a u16, but obtaining a value @@ -63,12 +66,12 @@ impl State { } pub unsafe fn seed(&mut self, seed: c_uint) { - self.ensure_x_ptr_init(); + unsafe { self.ensure_x_ptr_init() }; let mut s = seed as u64; if self.n == 0 { - *self.x_ptr = (s as u32).to_ne_bytes(); + unsafe { *self.x_ptr = (s as u32).to_ne_bytes() }; } else { self.i = if self.n == 31 || self.n == 7 { 3 } else { 1 }; @@ -79,11 +82,11 @@ impl State { // Conversion will always succeed (value is a 32-bit right- // shift of a 64-bit integer). - *self.x_ptr.add(k) = u32::try_from(s >> 32).unwrap().to_ne_bytes(); + unsafe { *self.x_ptr.add(k) = u32::try_from(s >> 32).unwrap().to_ne_bytes() }; } // ensure X contains at least one odd number - *self.x_ptr = (u32::from_ne_bytes(*self.x_ptr) | 1).to_ne_bytes(); + unsafe { *self.x_ptr = (u32::from_ne_bytes(*self.x_ptr) | 1).to_ne_bytes() }; } } } diff --git a/src/header/stdlib/sort.rs b/src/header/stdlib/sort.rs index f79d361bcd..11d0d81119 100644 --- a/src/header/stdlib/sort.rs +++ b/src/header/stdlib/sort.rs @@ -1,3 +1,6 @@ +// TODO: set this for entire crate when possible +#![deny(unsafe_op_in_unsafe_fn)] + use crate::platform::types::*; pub unsafe fn introsort( @@ -10,7 +13,7 @@ pub unsafe fn introsort( let maxdepth = 2 * log2(nel); introsort_helper(base, nel, width, maxdepth, comp); */ - insertion_sort(base, nel, width, comp); + unsafe { insertion_sort(base, nel, width, comp) }; } // NOTE: if num is 0, the result should be considered undefined @@ -41,23 +44,23 @@ unsafe fn introsort_helper( // to introsort_helper() loop { if nel < THRESHOLD { - insertion_sort(base, nel, width, comp); + unsafe { insertion_sort(base, nel, width, comp) }; break; } else if nel > 1 { if maxdepth == 0 { - heapsort(base, nel, width, comp); + unsafe { heapsort(base, nel, width, comp) }; break; } else { - let (left, right) = partition(base, nel, width, comp); + let (left, right) = unsafe { partition(base, nel, width, comp) }; let right_base = unsafe { base.add((right + 1) * width) }; let right_nel = nel - (right + 1); maxdepth -= 1; if left < nel - right { - introsort_helper(base, left, width, maxdepth, comp); + unsafe { introsort_helper(base, left, width, maxdepth, comp) }; base = right_base; nel = right_nel; } else { - introsort_helper(right_base, right_nel, width, maxdepth, comp); + unsafe { introsort_helper(right_base, right_nel, width, maxdepth, comp) }; nel = left; } } @@ -76,7 +79,7 @@ unsafe fn insertion_sort( let current = unsafe { base.add(j * width) }; let prev = unsafe { base.add((j + 1) * width) }; if comp(current as *const c_void, prev as *const c_void) > 0 { - swap(current, prev, width); + unsafe { swap(current, prev, width) }; } else { break; } @@ -90,14 +93,14 @@ unsafe fn heapsort( width: size_t, comp: extern "C" fn(*const c_void, *const c_void) -> c_int, ) { - heapify(base, nel, width, comp); + unsafe { heapify(base, nel, width, comp) }; let mut end = nel - 1; while end > 0 { let end_ptr = unsafe { base.add(end * width) }; - swap(end_ptr, base, width); + unsafe { swap(end_ptr, base, width) }; end -= 1; - heap_sift_down(base, 0, end, width, comp); + unsafe { heap_sift_down(base, 0, end, width, comp) }; } } @@ -111,7 +114,7 @@ unsafe fn heapify( let last_parent = (nel - 2) / 2; for start in (0..=last_parent).rev() { - heap_sift_down(base, start, nel - 1, width, comp); + unsafe { heap_sift_down(base, start, nel - 1, width, comp) }; } } @@ -148,7 +151,7 @@ unsafe fn heap_sift_down( if swap_idx == root { break; } else { - swap(root_ptr, swap_ptr, width); + unsafe { swap(root_ptr, swap_ptr, width) }; root = swap_idx; } } @@ -163,7 +166,7 @@ unsafe fn partition( ) -> (size_t, size_t) { // calculate the median of the first, middle, and last elements and use it as the pivot // to do fewer comparisons, also swap the elements into their correct positions - let mut pivot = median_of_three(base, nel, width, comp); + let mut pivot = unsafe { median_of_three(base, nel, width, comp) }; let mut i = 1; let mut j = 1; @@ -178,14 +181,14 @@ unsafe fn partition( let comparison = comp(j_ptr as *const c_void, pivot_ptr as *const c_void); if comparison < 0 { - swap(i_ptr, j_ptr, width); + unsafe { swap(i_ptr, j_ptr, width) }; if i == pivot { pivot = j; } i += 1; j += 1; } else if comparison > 0 { - swap(j_ptr, n_ptr, width); + unsafe { swap(j_ptr, n_ptr, width) }; if n == pivot { pivot = j; } @@ -209,12 +212,12 @@ unsafe fn median_of_three( let mid = unsafe { base.add(pivot * width) }; let last = unsafe { base.add((nel - 1) * width) }; if comp(mid as *const c_void, base as *const c_void) < 0 { - swap(mid, base, width); + unsafe { swap(mid, base, width) }; } if comp(last as *const c_void, mid as *const c_void) < 0 { - swap(mid, last, width); + unsafe { swap(mid, last, width) }; if comp(mid as *const c_void, base as *const c_void) < 0 { - swap(mid, base, width); + unsafe { swap(mid, base, width) }; } }