Skip to content

Commit 60d4450

Browse files
committed
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.
1 parent bf79280 commit 60d4450

File tree

6 files changed

+167
-51
lines changed

6 files changed

+167
-51
lines changed

builtins-test-intrinsics/src/main.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -649,14 +649,14 @@ fn something_with_a_dtor(f: &dyn Fn()) {
649649
f();
650650
}
651651

652-
#[no_mangle]
652+
#[unsafe(no_mangle)]
653653
#[cfg(not(thumb))]
654654
fn main(_argc: core::ffi::c_int, _argv: *const *const u8) -> core::ffi::c_int {
655655
run();
656656
0
657657
}
658658

659-
#[no_mangle]
659+
#[unsafe(no_mangle)]
660660
#[cfg(thumb)]
661661
pub fn _start() -> ! {
662662
run();
@@ -669,30 +669,30 @@ pub fn _start() -> ! {
669669
extern "C" {}
670670

671671
// ARM targets need these symbols
672-
#[no_mangle]
672+
#[unsafe(no_mangle)]
673673
pub fn __aeabi_unwind_cpp_pr0() {}
674674

675-
#[no_mangle]
675+
#[unsafe(no_mangle)]
676676
pub fn __aeabi_unwind_cpp_pr1() {}
677677

678678
#[cfg(not(any(windows, target_os = "cygwin")))]
679679
#[allow(non_snake_case)]
680-
#[no_mangle]
680+
#[unsafe(no_mangle)]
681681
pub fn _Unwind_Resume() {}
682682

683683
#[cfg(not(any(windows, target_os = "cygwin")))]
684684
#[lang = "eh_personality"]
685-
#[no_mangle]
685+
#[unsafe(no_mangle)]
686686
pub extern "C" fn eh_personality() {}
687687

688688
#[cfg(any(all(windows, target_env = "gnu"), target_os = "cygwin"))]
689689
mod mingw_unwinding {
690-
#[no_mangle]
690+
#[unsafe(no_mangle)]
691691
pub fn rust_eh_personality() {}
692-
#[no_mangle]
692+
#[unsafe(no_mangle)]
693693
pub fn rust_eh_unwind_resume() {}
694-
#[no_mangle]
694+
#[unsafe(no_mangle)]
695695
pub fn rust_eh_register_frames() {}
696-
#[no_mangle]
696+
#[unsafe(no_mangle)]
697697
pub fn rust_eh_unregister_frames() {}
698698
}

compiler-builtins/src/arm.rs

+143-33
Original file line numberDiff line numberDiff line change
@@ -76,90 +76,200 @@ intrinsics! {
7676
);
7777
}
7878

79-
// FIXME: The `*4` and `*8` variants should be defined as aliases.
79+
// FIXME(arm): The `*4` and `*8` variants should be defined as aliases.
8080

81+
/// `memcpy` provided with the `aapcs` ABI.
82+
///
83+
/// # Safety
84+
///
85+
/// Usual `memcpy` requirements apply.
8186
#[cfg(not(target_vendor = "apple"))]
82-
pub unsafe extern "aapcs" fn __aeabi_memcpy(dest: *mut u8, src: *const u8, n: usize) {
83-
crate::mem::memcpy(dest, src, n);
87+
pub unsafe extern "aapcs" fn __aeabi_memcpy(dst: *mut u8, src: *const u8, n: usize) {
88+
// SAFETY: memcpy preconditions apply.
89+
unsafe { crate::mem::memcpy(dst, src, n) };
8490
}
8591

92+
/// `memcpy` for 4-byte alignment.
93+
///
94+
/// # Safety
95+
///
96+
/// Usual `memcpy` requirements apply. Additionally, `dest` and `src` must be aligned to
97+
/// four bytes.
8698
#[cfg(not(target_vendor = "apple"))]
87-
pub unsafe extern "aapcs" fn __aeabi_memcpy4(dest: *mut u8, src: *const u8, n: usize) {
99+
pub unsafe extern "aapcs" fn __aeabi_memcpy4(dst: *mut u8, src: *const u8, n: usize) {
88100
// We are guaranteed 4-alignment, so accessing at u32 is okay.
89-
let mut dest = dest as *mut u32;
90-
let mut src = src as *mut u32;
101+
let mut dst = dst.cast::<u32>();
102+
let mut src = src.cast::<u32>();
103+
debug_assert!(dst.is_aligned());
104+
debug_assert!(src.is_aligned());
91105
let mut n = n;
92106

93107
while n >= 4 {
94-
*dest = *src;
95-
dest = dest.offset(1);
96-
src = src.offset(1);
108+
// SAFETY: `dst` and `src` are both valid for at least 4 bytes, from
109+
// `memcpy` preconditions and the loop guard.
110+
unsafe { *dst = *src };
111+
112+
// TODO
113+
unsafe {
114+
dst = dst.offset(1);
115+
src = src.offset(1);
116+
}
117+
97118
n -= 4;
98119
}
99120

100-
__aeabi_memcpy(dest as *mut u8, src as *const u8, n);
121+
// SAFETY: `dst` and `src` will still be valid for `n` bytes
122+
unsafe { __aeabi_memcpy(dst.cast::<u8>(), src.cast::<u8>(), n) };
101123
}
102124

125+
/// `memcpy` for 8-byte alignment.
126+
///
127+
/// # Safety
128+
///
129+
/// Usual `memcpy` requirements apply. Additionally, `dest` and `src` must be aligned to
130+
/// eight bytes.
103131
#[cfg(not(target_vendor = "apple"))]
104-
pub unsafe extern "aapcs" fn __aeabi_memcpy8(dest: *mut u8, src: *const u8, n: usize) {
105-
__aeabi_memcpy4(dest, src, n);
132+
pub unsafe extern "aapcs" fn __aeabi_memcpy8(dst: *mut u8, src: *const u8, n: usize) {
133+
debug_assert!(dst.addr() & 7 == 0);
134+
debug_assert!(src.addr() & 7 == 0);
135+
136+
// SAFETY: memcpy preconditions apply, less strict alignment.
137+
unsafe { __aeabi_memcpy4(dst, src, n) };
106138
}
107139

140+
/// `memmove` provided with the `aapcs` ABI.
141+
///
142+
/// # Safety
143+
///
144+
/// Usual `memmove` requirements apply.
108145
#[cfg(not(target_vendor = "apple"))]
109-
pub unsafe extern "aapcs" fn __aeabi_memmove(dest: *mut u8, src: *const u8, n: usize) {
110-
crate::mem::memmove(dest, src, n);
146+
pub unsafe extern "aapcs" fn __aeabi_memmove(dst: *mut u8, src: *const u8, n: usize) {
147+
// SAFETY: memmove preconditions apply.
148+
unsafe { crate::mem::memmove(dst, src, n) };
111149
}
112150

151+
/// `memmove` for 4-byte alignment.
152+
///
153+
/// # Safety
154+
///
155+
/// Usual `memmove` requirements apply. Additionally, `dest` and `src` must be aligned to
156+
/// four bytes.
113157
#[cfg(not(any(target_vendor = "apple", target_env = "msvc")))]
114-
pub unsafe extern "aapcs" fn __aeabi_memmove4(dest: *mut u8, src: *const u8, n: usize) {
115-
__aeabi_memmove(dest, src, n);
158+
pub unsafe extern "aapcs" fn __aeabi_memmove4(dst: *mut u8, src: *const u8, n: usize) {
159+
debug_assert!(dst.addr() & 3 == 0);
160+
debug_assert!(src.addr() & 3 == 0);
161+
162+
// SAFETY: same preconditions, less strict aligment.
163+
unsafe { __aeabi_memmove(dst, src, n) };
116164
}
117165

166+
/// `memmove` for 8-byte alignment.
167+
///
168+
/// # Safety
169+
///
170+
/// Usual `memmove` requirements apply. Additionally, `dst` and `src` must be aligned to
171+
/// eight bytes.
118172
#[cfg(not(any(target_vendor = "apple", target_env = "msvc")))]
119-
pub unsafe extern "aapcs" fn __aeabi_memmove8(dest: *mut u8, src: *const u8, n: usize) {
120-
__aeabi_memmove(dest, src, n);
173+
pub unsafe extern "aapcs" fn __aeabi_memmove8(dst: *mut u8, src: *const u8, n: usize) {
174+
debug_assert!(dst.addr() & 7 == 0);
175+
debug_assert!(src.addr() & 7 == 0);
176+
177+
// SAFETY: memmove preconditions apply, less strict alignment.
178+
unsafe { __aeabi_memmove(dst, src, n) };
121179
}
122180

181+
/// `memset` provided with the `aapcs` ABI.
182+
///
183+
/// # Safety
184+
///
185+
/// Usual `memset` requirements apply.
123186
#[cfg(not(target_vendor = "apple"))]
124-
pub unsafe extern "aapcs" fn __aeabi_memset(dest: *mut u8, n: usize, c: i32) {
187+
pub unsafe extern "aapcs" fn __aeabi_memset(dst: *mut u8, n: usize, c: i32) {
125188
// Note the different argument order
126-
crate::mem::memset(dest, c, n);
189+
// SAFETY: memset preconditions apply.
190+
unsafe { crate::mem::memset(dst, c, n) };
127191
}
128192

193+
/// `memset` for 4-byte alignment.
194+
///
195+
/// # Safety
196+
///
197+
/// Usual `memset` requirements apply. Additionally, `dest` and `src` must be aligned to
198+
/// four bytes.
129199
#[cfg(not(target_vendor = "apple"))]
130-
pub unsafe extern "aapcs" fn __aeabi_memset4(dest: *mut u8, n: usize, c: i32) {
131-
let mut dest = dest as *mut u32;
200+
pub unsafe extern "aapcs" fn __aeabi_memset4(dst: *mut u8, n: usize, c: i32) {
201+
let mut dst = dst.cast::<u32>();
202+
debug_assert!(dst.is_aligned());
132203
let mut n = n;
133204

134205
let byte = (c as u32) & 0xff;
135206
let c = (byte << 24) | (byte << 16) | (byte << 8) | byte;
136207

137208
while n >= 4 {
138-
*dest = c;
139-
dest = dest.offset(1);
209+
// SAFETY: `dst` is valid for at least 4 bytes, from `memset` preconditions and
210+
// the loop guard.
211+
unsafe { *dst = c };
212+
// TODO
213+
unsafe {
214+
dst = dst.offset(1);
215+
}
140216
n -= 4;
141217
}
142218

143-
__aeabi_memset(dest as *mut u8, n, byte as i32);
219+
// SAFETY: `dst` will still be valid for `n` bytes
220+
unsafe { __aeabi_memset(dst.cast::<u8>(), n, byte as i32) };
144221
}
145222

223+
/// `memset` for 8-byte alignment.
224+
///
225+
/// # Safety
226+
///
227+
/// Usual `memset` requirements apply. Additionally, `dst` and `src` must be aligned to
228+
/// eight bytes.
146229
#[cfg(not(target_vendor = "apple"))]
147-
pub unsafe extern "aapcs" fn __aeabi_memset8(dest: *mut u8, n: usize, c: i32) {
148-
__aeabi_memset4(dest, n, c);
230+
pub unsafe extern "aapcs" fn __aeabi_memset8(dst: *mut u8, n: usize, c: i32) {
231+
debug_assert!(dst.addr() & 7 == 0);
232+
233+
// SAFETY: memset preconditions apply, less strict alignment.
234+
unsafe { __aeabi_memset4(dst, n, c) };
149235
}
150236

237+
/// `memclr` provided with the `aapcs` ABI.
238+
///
239+
/// # Safety
240+
///
241+
/// Usual `memclr` requirements apply.
151242
#[cfg(not(target_vendor = "apple"))]
152-
pub unsafe extern "aapcs" fn __aeabi_memclr(dest: *mut u8, n: usize) {
153-
__aeabi_memset(dest, n, 0);
243+
pub unsafe extern "aapcs" fn __aeabi_memclr(dst: *mut u8, n: usize) {
244+
// SAFETY: memclr preconditions apply, less strict alignment.
245+
unsafe { __aeabi_memset(dst, n, 0) };
154246
}
155247

248+
/// `memclr` for 4-byte alignment.
249+
///
250+
/// # Safety
251+
///
252+
/// Usual `memclr` requirements apply. Additionally, `dest` and `src` must be aligned to
253+
/// four bytes.
156254
#[cfg(not(any(target_vendor = "apple", target_env = "msvc")))]
157-
pub unsafe extern "aapcs" fn __aeabi_memclr4(dest: *mut u8, n: usize) {
158-
__aeabi_memset4(dest, n, 0);
255+
pub unsafe extern "aapcs" fn __aeabi_memclr4(dst: *mut u8, n: usize) {
256+
debug_assert!(dst.addr() & 3 == 0);
257+
258+
// SAFETY: memclr preconditions apply, less strict alignment.
259+
unsafe { __aeabi_memset4(dst, n, 0) };
159260
}
160261

262+
/// `memclr` for 8-byte alignment.
263+
///
264+
/// # Safety
265+
///
266+
/// Usual `memclr` requirements apply. Additionally, `dst` and `src` must be aligned to
267+
/// eight bytes.
161268
#[cfg(not(any(target_vendor = "apple", target_env = "msvc")))]
162-
pub unsafe extern "aapcs" fn __aeabi_memclr8(dest: *mut u8, n: usize) {
163-
__aeabi_memset4(dest, n, 0);
269+
pub unsafe extern "aapcs" fn __aeabi_memclr8(dst: *mut u8, n: usize) {
270+
debug_assert!(dst.addr() & 7 == 0);
271+
272+
// SAFETY: memclr preconditions apply, less strict alignment.
273+
unsafe { __aeabi_memset4(dst, n, 0) };
164274
}
165275
}

compiler-builtins/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
#![allow(clippy::manual_swap)]
2323
// Support compiling on both stage0 and stage1 which may differ in supported stable features.
2424
#![allow(stable_features)]
25+
// By default, disallow this as it is forbidden in edition 2024. There is a lot of unsafe code to
26+
// be migrated, however, so exceptions exist.
27+
#![warn(unsafe_op_in_unsafe_fn)]
2528

2629
// We disable #[no_mangle] for tests so that we can verify the test results
2730
// against the native compiler-rt implementations of the builtins.

compiler-builtins/src/macros.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ macro_rules! intrinsics {
256256

257257
#[cfg(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64"), not(feature = "mangled-names")))]
258258
mod $name {
259-
#[no_mangle]
259+
#[unsafe(no_mangle)]
260260
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
261261
$(#[$($attr)*])*
262262
extern $abi fn $name( $($argname: u16),* ) $(-> $ret)? {
@@ -292,7 +292,7 @@ macro_rules! intrinsics {
292292

293293
#[cfg(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64"), not(feature = "mangled-names")))]
294294
mod $name {
295-
#[no_mangle]
295+
#[unsafe(no_mangle)]
296296
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
297297
$(#[$($attr)*])*
298298
extern $abi fn $name( $($argname: $ty),* ) -> u16 {
@@ -333,7 +333,7 @@ macro_rules! intrinsics {
333333

334334
#[cfg(all(target_arch = "arm", not(feature = "mangled-names")))]
335335
mod $name {
336-
#[no_mangle]
336+
#[unsafe(no_mangle)]
337337
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
338338
$(#[$($attr)*])*
339339
extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
@@ -343,7 +343,7 @@ macro_rules! intrinsics {
343343

344344
#[cfg(all(target_arch = "arm", not(feature = "mangled-names")))]
345345
mod $alias {
346-
#[no_mangle]
346+
#[unsafe(no_mangle)]
347347
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
348348
$(#[$($attr)*])*
349349
extern "aapcs" fn $alias( $($argname: $ty),* ) $(-> $ret)? {
@@ -410,7 +410,7 @@ macro_rules! intrinsics {
410410
#[cfg(all(feature = "mem", not(feature = "mangled-names")))]
411411
mod $name {
412412
$(#[$($attr)*])*
413-
#[no_mangle]
413+
#[unsafe(no_mangle)]
414414
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
415415
unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
416416
super::$name($($argname),*)
@@ -485,10 +485,11 @@ macro_rules! intrinsics {
485485
#[cfg(not(feature = "mangled-names"))]
486486
mod $name {
487487
$(#[$($attr)*])*
488-
#[no_mangle]
488+
#[unsafe(no_mangle)]
489489
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
490490
$(unsafe $($empty)?)? extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
491-
super::$name($($argname),*)
491+
// SAFETY: same preconditions.
492+
$(unsafe $($empty)?)? { super::$name($($argname),*) }
492493
}
493494
}
494495

compiler-builtins/src/mem/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Trying to satisfy clippy here is hopeless
22
#![allow(clippy::style)]
3+
// FIXME(e2024): this eventually needs to be removed.
4+
#![allow(unsafe_op_in_unsafe_fn)]
35

46
#[allow(warnings)]
57
#[cfg(target_pointer_width = "16")]

compiler-builtins/src/x86_64.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ intrinsics! {
4444
// HACK(https://github.com/rust-lang/rust/issues/62785): x86_64-unknown-uefi needs special LLVM
4545
// support unless we emit the _fltused
4646
mod _fltused {
47-
#[no_mangle]
47+
#[unsafe(no_mangle)]
4848
#[used]
4949
#[cfg(target_os = "uefi")]
5050
static _fltused: i32 = 0;

0 commit comments

Comments
 (0)