Warn on unsafe_op_in_unsafe_fn by default
Edition 2024 requires that we avoid this. There is a lot of code that will need to be adjusted, so start the process here with a warning that will show up in CI.
This commit is contained in:
parent
99202af075
commit
975617e8d4
6 changed files with 172 additions and 51 deletions
|
|
@ -649,14 +649,14 @@ fn something_with_a_dtor(f: &dyn Fn()) {
|
|||
f();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
#[cfg(not(thumb))]
|
||||
fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
|
||||
run();
|
||||
0
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
#[cfg(thumb)]
|
||||
pub fn _start() -> ! {
|
||||
run();
|
||||
|
|
@ -669,30 +669,30 @@ pub fn _start() -> ! {
|
|||
extern "C" {}
|
||||
|
||||
// ARM targets need these symbols
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn __aeabi_unwind_cpp_pr0() {}
|
||||
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn __aeabi_unwind_cpp_pr1() {}
|
||||
|
||||
#[cfg(not(any(windows, target_os = "cygwin")))]
|
||||
#[allow(non_snake_case)]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn _Unwind_Resume() {}
|
||||
|
||||
#[cfg(not(any(windows, target_os = "cygwin")))]
|
||||
#[lang = "eh_personality"]
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "C" fn eh_personality() {}
|
||||
|
||||
#[cfg(any(all(windows, target_env = "gnu"), target_os = "cygwin"))]
|
||||
mod mingw_unwinding {
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn rust_eh_personality() {}
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn rust_eh_unwind_resume() {}
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn rust_eh_register_frames() {}
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn rust_eh_unregister_frames() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,90 +76,205 @@ intrinsics! {
|
|||
);
|
||||
}
|
||||
|
||||
// FIXME: The `*4` and `*8` variants should be defined as aliases.
|
||||
// FIXME(arm): The `*4` and `*8` variants should be defined as aliases.
|
||||
|
||||
/// `memcpy` provided with the `aapcs` ABI.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Usual `memcpy` requirements apply.
|
||||
#[cfg(not(target_vendor = "apple"))]
|
||||
pub unsafe extern "aapcs" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, n: usize) {
|
||||
crate::mem::memcpy(dest, src, n);
|
||||
pub unsafe extern "aapcs" fn __aeabi_memcpy(dst: *mut u8, src: *const u8, n: usize) {
|
||||
// SAFETY: memcpy preconditions apply.
|
||||
unsafe { crate::mem::memcpy(dst, src, n) };
|
||||
}
|
||||
|
||||
/// `memcpy` for 4-byte alignment.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Usual `memcpy` requirements apply. Additionally, `dest` and `src` must be aligned to
|
||||
/// four bytes.
|
||||
#[cfg(not(target_vendor = "apple"))]
|
||||
pub unsafe extern "aapcs" fn __aeabi_memcpy4(dest: *mut u8, src: *const u8, n: usize) {
|
||||
pub unsafe extern "aapcs" fn __aeabi_memcpy4(dst: *mut u8, src: *const u8, n: usize) {
|
||||
// We are guaranteed 4-alignment, so accessing at u32 is okay.
|
||||
let mut dest = dest as *mut u32;
|
||||
let mut src = src as *mut u32;
|
||||
let mut dst = dst.cast::<u32>();
|
||||
let mut src = src.cast::<u32>();
|
||||
debug_assert!(dst.is_aligned());
|
||||
debug_assert!(src.is_aligned());
|
||||
let mut n = n;
|
||||
|
||||
while n >= 4 {
|
||||
*dest = *src;
|
||||
dest = dest.offset(1);
|
||||
src = src.offset(1);
|
||||
// SAFETY: `dst` and `src` are both valid for at least 4 bytes, from
|
||||
// `memcpy` preconditions and the loop guard.
|
||||
unsafe { *dst = *src };
|
||||
|
||||
// FIXME(addr): if we can make this end-of-address-space safe without losing
|
||||
// performance, we may want to consider that.
|
||||
// SAFETY: memcpy is not expected to work at the end of the address space
|
||||
unsafe {
|
||||
dst = dst.offset(1);
|
||||
src = src.offset(1);
|
||||
}
|
||||
|
||||
n -= 4;
|
||||
}
|
||||
|
||||
__aeabi_memcpy(dest as *mut u8, src as *const u8, n);
|
||||
// SAFETY: `dst` and `src` will still be valid for `n` bytes
|
||||
unsafe { __aeabi_memcpy(dst.cast::<u8>(), src.cast::<u8>(), n) };
|
||||
}
|
||||
|
||||
/// `memcpy` for 8-byte alignment.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Usual `memcpy` requirements apply. Additionally, `dest` and `src` must be aligned to
|
||||
/// eight bytes.
|
||||
#[cfg(not(target_vendor = "apple"))]
|
||||
pub unsafe extern "aapcs" fn __aeabi_memcpy8(dest: *mut u8, src: *const u8, n: usize) {
|
||||
__aeabi_memcpy4(dest, src, n);
|
||||
pub unsafe extern "aapcs" fn __aeabi_memcpy8(dst: *mut u8, src: *const u8, n: usize) {
|
||||
debug_assert!(dst.addr() & 7 == 0);
|
||||
debug_assert!(src.addr() & 7 == 0);
|
||||
|
||||
// SAFETY: memcpy preconditions apply, less strict alignment.
|
||||
unsafe { __aeabi_memcpy4(dst, src, n) };
|
||||
}
|
||||
|
||||
/// `memmove` provided with the `aapcs` ABI.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Usual `memmove` requirements apply.
|
||||
#[cfg(not(target_vendor = "apple"))]
|
||||
pub unsafe extern "aapcs" fn __aeabi_memmove(dest: *mut u8, src: *const u8, n: usize) {
|
||||
crate::mem::memmove(dest, src, n);
|
||||
pub unsafe extern "aapcs" fn __aeabi_memmove(dst: *mut u8, src: *const u8, n: usize) {
|
||||
// SAFETY: memmove preconditions apply.
|
||||
unsafe { crate::mem::memmove(dst, src, n) };
|
||||
}
|
||||
|
||||
/// `memmove` for 4-byte alignment.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Usual `memmove` requirements apply. Additionally, `dest` and `src` must be aligned to
|
||||
/// four bytes.
|
||||
#[cfg(not(any(target_vendor = "apple", target_env = "msvc")))]
|
||||
pub unsafe extern "aapcs" fn __aeabi_memmove4(dest: *mut u8, src: *const u8, n: usize) {
|
||||
__aeabi_memmove(dest, src, n);
|
||||
pub unsafe extern "aapcs" fn __aeabi_memmove4(dst: *mut u8, src: *const u8, n: usize) {
|
||||
debug_assert!(dst.addr() & 3 == 0);
|
||||
debug_assert!(src.addr() & 3 == 0);
|
||||
|
||||
// SAFETY: same preconditions, less strict aligment.
|
||||
unsafe { __aeabi_memmove(dst, src, n) };
|
||||
}
|
||||
|
||||
/// `memmove` for 8-byte alignment.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Usual `memmove` requirements apply. Additionally, `dst` and `src` must be aligned to
|
||||
/// eight bytes.
|
||||
#[cfg(not(any(target_vendor = "apple", target_env = "msvc")))]
|
||||
pub unsafe extern "aapcs" fn __aeabi_memmove8(dest: *mut u8, src: *const u8, n: usize) {
|
||||
__aeabi_memmove(dest, src, n);
|
||||
pub unsafe extern "aapcs" fn __aeabi_memmove8(dst: *mut u8, src: *const u8, n: usize) {
|
||||
debug_assert!(dst.addr() & 7 == 0);
|
||||
debug_assert!(src.addr() & 7 == 0);
|
||||
|
||||
// SAFETY: memmove preconditions apply, less strict alignment.
|
||||
unsafe { __aeabi_memmove(dst, src, n) };
|
||||
}
|
||||
|
||||
/// `memset` provided with the `aapcs` ABI.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Usual `memset` requirements apply.
|
||||
#[cfg(not(target_vendor = "apple"))]
|
||||
pub unsafe extern "aapcs" fn __aeabi_memset(dest: *mut u8, n: usize, c: i32) {
|
||||
pub unsafe extern "aapcs" fn __aeabi_memset(dst: *mut u8, n: usize, c: i32) {
|
||||
// Note the different argument order
|
||||
crate::mem::memset(dest, c, n);
|
||||
// SAFETY: memset preconditions apply.
|
||||
unsafe { crate::mem::memset(dst, c, n) };
|
||||
}
|
||||
|
||||
/// `memset` for 4-byte alignment.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Usual `memset` requirements apply. Additionally, `dest` and `src` must be aligned to
|
||||
/// four bytes.
|
||||
#[cfg(not(target_vendor = "apple"))]
|
||||
pub unsafe extern "aapcs" fn __aeabi_memset4(dest: *mut u8, n: usize, c: i32) {
|
||||
let mut dest = dest as *mut u32;
|
||||
pub unsafe extern "aapcs" fn __aeabi_memset4(dst: *mut u8, n: usize, c: i32) {
|
||||
let mut dst = dst.cast::<u32>();
|
||||
debug_assert!(dst.is_aligned());
|
||||
let mut n = n;
|
||||
|
||||
let byte = (c as u32) & 0xff;
|
||||
let c = (byte << 24) | (byte << 16) | (byte << 8) | byte;
|
||||
|
||||
while n >= 4 {
|
||||
*dest = c;
|
||||
dest = dest.offset(1);
|
||||
// SAFETY: `dst` is valid for at least 4 bytes, from `memset` preconditions and
|
||||
// the loop guard.
|
||||
unsafe { *dst = c };
|
||||
|
||||
// FIXME(addr): if we can make this end-of-address-space safe without losing
|
||||
// performance, we may want to consider that.
|
||||
// SAFETY: memcpy is not expected to work at the end of the address space
|
||||
unsafe {
|
||||
dst = dst.offset(1);
|
||||
}
|
||||
n -= 4;
|
||||
}
|
||||
|
||||
__aeabi_memset(dest as *mut u8, n, byte as i32);
|
||||
// SAFETY: `dst` will still be valid for `n` bytes
|
||||
unsafe { __aeabi_memset(dst.cast::<u8>(), n, byte as i32) };
|
||||
}
|
||||
|
||||
/// `memset` for 8-byte alignment.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Usual `memset` requirements apply. Additionally, `dst` and `src` must be aligned to
|
||||
/// eight bytes.
|
||||
#[cfg(not(target_vendor = "apple"))]
|
||||
pub unsafe extern "aapcs" fn __aeabi_memset8(dest: *mut u8, n: usize, c: i32) {
|
||||
__aeabi_memset4(dest, n, c);
|
||||
pub unsafe extern "aapcs" fn __aeabi_memset8(dst: *mut u8, n: usize, c: i32) {
|
||||
debug_assert!(dst.addr() & 7 == 0);
|
||||
|
||||
// SAFETY: memset preconditions apply, less strict alignment.
|
||||
unsafe { __aeabi_memset4(dst, n, c) };
|
||||
}
|
||||
|
||||
/// `memclr` provided with the `aapcs` ABI.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Usual `memclr` requirements apply.
|
||||
#[cfg(not(target_vendor = "apple"))]
|
||||
pub unsafe extern "aapcs" fn __aeabi_memclr(dest: *mut u8, n: usize) {
|
||||
__aeabi_memset(dest, n, 0);
|
||||
pub unsafe extern "aapcs" fn __aeabi_memclr(dst: *mut u8, n: usize) {
|
||||
// SAFETY: memclr preconditions apply, less strict alignment.
|
||||
unsafe { __aeabi_memset(dst, n, 0) };
|
||||
}
|
||||
|
||||
/// `memclr` for 4-byte alignment.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Usual `memclr` requirements apply. Additionally, `dest` and `src` must be aligned to
|
||||
/// four bytes.
|
||||
#[cfg(not(any(target_vendor = "apple", target_env = "msvc")))]
|
||||
pub unsafe extern "aapcs" fn __aeabi_memclr4(dest: *mut u8, n: usize) {
|
||||
__aeabi_memset4(dest, n, 0);
|
||||
pub unsafe extern "aapcs" fn __aeabi_memclr4(dst: *mut u8, n: usize) {
|
||||
debug_assert!(dst.addr() & 3 == 0);
|
||||
|
||||
// SAFETY: memclr preconditions apply, less strict alignment.
|
||||
unsafe { __aeabi_memset4(dst, n, 0) };
|
||||
}
|
||||
|
||||
/// `memclr` for 8-byte alignment.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Usual `memclr` requirements apply. Additionally, `dst` and `src` must be aligned to
|
||||
/// eight bytes.
|
||||
#[cfg(not(any(target_vendor = "apple", target_env = "msvc")))]
|
||||
pub unsafe extern "aapcs" fn __aeabi_memclr8(dest: *mut u8, n: usize) {
|
||||
__aeabi_memset4(dest, n, 0);
|
||||
pub unsafe extern "aapcs" fn __aeabi_memclr8(dst: *mut u8, n: usize) {
|
||||
debug_assert!(dst.addr() & 7 == 0);
|
||||
|
||||
// SAFETY: memclr preconditions apply, less strict alignment.
|
||||
unsafe { __aeabi_memset4(dst, n, 0) };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@
|
|||
#![allow(clippy::manual_swap)]
|
||||
// Support compiling on both stage0 and stage1 which may differ in supported stable features.
|
||||
#![allow(stable_features)]
|
||||
// By default, disallow this as it is forbidden in edition 2024. There is a lot of unsafe code to
|
||||
// be migrated, however, so exceptions exist.
|
||||
#![warn(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
// We disable #[no_mangle] for tests so that we can verify the test results
|
||||
// against the native compiler-rt implementations of the builtins.
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ macro_rules! intrinsics {
|
|||
|
||||
#[cfg(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64"), not(feature = "mangled-names")))]
|
||||
mod $name {
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
|
||||
$(#[$($attr)*])*
|
||||
extern $abi fn $name( $($argname: u16),* ) $(-> $ret)? {
|
||||
|
|
@ -292,7 +292,7 @@ macro_rules! intrinsics {
|
|||
|
||||
#[cfg(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64"), not(feature = "mangled-names")))]
|
||||
mod $name {
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
|
||||
$(#[$($attr)*])*
|
||||
extern $abi fn $name( $($argname: $ty),* ) -> u16 {
|
||||
|
|
@ -333,7 +333,7 @@ macro_rules! intrinsics {
|
|||
|
||||
#[cfg(all(target_arch = "arm", not(feature = "mangled-names")))]
|
||||
mod $name {
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
|
||||
$(#[$($attr)*])*
|
||||
extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
|
||||
|
|
@ -343,7 +343,7 @@ macro_rules! intrinsics {
|
|||
|
||||
#[cfg(all(target_arch = "arm", not(feature = "mangled-names")))]
|
||||
mod $alias {
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
|
||||
$(#[$($attr)*])*
|
||||
extern "aapcs" fn $alias( $($argname: $ty),* ) $(-> $ret)? {
|
||||
|
|
@ -410,7 +410,7 @@ macro_rules! intrinsics {
|
|||
#[cfg(all(feature = "mem", not(feature = "mangled-names")))]
|
||||
mod $name {
|
||||
$(#[$($attr)*])*
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
|
||||
unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
|
||||
super::$name($($argname),*)
|
||||
|
|
@ -485,10 +485,11 @@ macro_rules! intrinsics {
|
|||
#[cfg(not(feature = "mangled-names"))]
|
||||
mod $name {
|
||||
$(#[$($attr)*])*
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
|
||||
$(unsafe $($empty)?)? extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
|
||||
super::$name($($argname),*)
|
||||
// SAFETY: same preconditions.
|
||||
$(unsafe $($empty)?)? { super::$name($($argname),*) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
// Trying to satisfy clippy here is hopeless
|
||||
#![allow(clippy::style)]
|
||||
// FIXME(e2024): this eventually needs to be removed.
|
||||
#![allow(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
#[allow(warnings)]
|
||||
#[cfg(target_pointer_width = "16")]
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ intrinsics! {
|
|||
// HACK(https://github.com/rust-lang/rust/issues/62785): x86_64-unknown-uefi needs special LLVM
|
||||
// support unless we emit the _fltused
|
||||
mod _fltused {
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
#[used]
|
||||
#[cfg(target_os = "uefi")]
|
||||
static _fltused: i32 = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue