Skip to content

Commit 1a5e486

Browse files
authored
Rollup merge of #139753 - folkertdev:naked-function-unsafe-attribute, r=tgross35,traviscross
Make `#[naked]` an unsafe attribute tracking issue: #138997 Per #134213 (comment), the `#[naked]` attribute is now an unsafe attribute (in any edition). This can only be merged when the above PRs are merged, I'd just like to see if there are any CI surprises here, and maybe there is early review feedback too. r? ``@traviscross``
2 parents aad59a3 + 41ddf86 commit 1a5e486

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+375
-403
lines changed

Diff for: compiler/rustc_builtin_macros/messages.ftl

+2-2
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,9 @@ builtin_macros_multiple_defaults = multiple declared defaults
247247
.suggestion = make `{$ident}` default
248248
249249
builtin_macros_naked_functions_testing_attribute =
250-
cannot use `#[naked]` with testing attributes
250+
cannot use `#[unsafe(naked)]` with testing attributes
251251
.label = function marked with testing attribute here
252-
.naked_attribute = `#[naked]` is incompatible with testing attributes
252+
.naked_attribute = `#[unsafe(naked)]` is incompatible with testing attributes
253253
254254
builtin_macros_no_default_variant = `#[derive(Default)]` on enum with no `#[default]`
255255
.label = this enum needs a unit variant marked with `#[default]`

Diff for: compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -387,11 +387,9 @@ global_asm! {
387387
}
388388

389389
#[cfg(all(not(jit), target_arch = "x86_64"))]
390-
#[naked]
390+
#[unsafe(naked)]
391391
extern "C" fn naked_test() {
392-
unsafe {
393-
naked_asm!("ret");
394-
}
392+
naked_asm!("ret")
395393
}
396394

397395
#[repr(C)]

Diff for: compiler/rustc_error_codes/src/error_codes/E0736.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Erroneous code example:
1111

1212
```compile_fail,E0736
1313
#[inline]
14-
#[naked]
14+
#[unsafe(naked)]
1515
fn foo() {}
1616
```
1717

Diff for: compiler/rustc_error_codes/src/error_codes/E0787.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Erroneous code example:
55
```compile_fail,E0787
66
#![feature(naked_functions)]
77
8-
#[naked]
8+
#[unsafe(naked)]
99
pub extern "C" fn f() -> u32 {
1010
42
1111
}

Diff for: compiler/rustc_feature/src/builtin_attrs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
517517

518518
// Linking:
519519
gated!(
520-
naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
520+
unsafe naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
521521
naked_functions, experimental!(naked)
522522
),
523523

Diff for: compiler/rustc_mir_build/src/check_unsafety.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -564,13 +564,17 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
564564
}
565565
}
566566
ExprKind::InlineAsm(box InlineAsmExpr {
567-
asm_macro: AsmMacro::Asm | AsmMacro::NakedAsm,
567+
asm_macro: asm_macro @ (AsmMacro::Asm | AsmMacro::NakedAsm),
568568
ref operands,
569569
template: _,
570570
options: _,
571571
line_spans: _,
572572
}) => {
573-
self.requires_unsafe(expr.span, UseOfInlineAssembly);
573+
// The `naked` attribute and the `naked_asm!` block form one atomic unit of
574+
// unsafety, and `naked_asm!` does not itself need to be wrapped in an unsafe block.
575+
if let AsmMacro::Asm = asm_macro {
576+
self.requires_unsafe(expr.span, UseOfInlineAssembly);
577+
}
574578

575579
// For inline asm, do not use `walk_expr`, since we want to handle the label block
576580
// specially.

Diff for: compiler/rustc_parse/src/validate_attr.rs

-6
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,6 @@ pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr:
194194
}
195195
}
196196
} else if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
197-
// Allow (but don't require) `#[unsafe(naked)]` so that compiler-builtins can upgrade to it.
198-
// FIXME(#139797): remove this special case when compiler-builtins has upgraded.
199-
if attr.has_name(sym::naked) {
200-
return;
201-
}
202-
203197
psess.dcx().emit_err(errors::InvalidAttrUnsafe {
204198
span: unsafe_span,
205199
name: attr_item.path.clone(),

Diff for: compiler/rustc_passes/messages.ftl

+4-4
Original file line numberDiff line numberDiff line change
@@ -508,17 +508,17 @@ passes_must_use_no_effect =
508508
`#[must_use]` has no effect when applied to {$article} {$target}
509509
510510
passes_naked_asm_outside_naked_fn =
511-
the `naked_asm!` macro can only be used in functions marked with `#[naked]`
511+
the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
512512
513513
passes_naked_functions_asm_block =
514514
naked functions must contain a single `naked_asm!` invocation
515515
.label_multiple_asm = multiple `naked_asm!` invocations are not allowed in naked functions
516516
.label_non_asm = not allowed in naked functions
517517
518518
passes_naked_functions_incompatible_attribute =
519-
attribute incompatible with `#[naked]`
520-
.label = the `{$attr}` attribute is incompatible with `#[naked]`
521-
.naked_attribute = function marked with `#[naked]` here
519+
attribute incompatible with `#[unsafe(naked)]`
520+
.label = the `{$attr}` attribute is incompatible with `#[unsafe(naked)]`
521+
.naked_attribute = function marked with `#[unsafe(naked)]` here
522522
523523
passes_naked_functions_must_naked_asm =
524524
the `asm!` macro is not allowed in naked functions

Diff for: src/doc/unstable-book/src/compiler-flags/sanitizer.md

+17-20
Original file line numberDiff line numberDiff line change
@@ -247,34 +247,31 @@ See the [Clang ControlFlowIntegrity documentation][clang-cfi] for more details.
247247
```rust,ignore (making doc tests pass cross-platform is hard)
248248
#![feature(naked_functions)]
249249

250-
use std::arch::asm;
250+
use std::arch::naked_asm;
251251
use std::mem;
252252

253253
fn add_one(x: i32) -> i32 {
254254
x + 1
255255
}
256256

257-
#[naked]
257+
#[unsafe(naked)]
258258
pub extern "C" fn add_two(x: i32) {
259259
// x + 2 preceded by a landing pad/nop block
260-
unsafe {
261-
asm!(
262-
"
263-
nop
264-
nop
265-
nop
266-
nop
267-
nop
268-
nop
269-
nop
270-
nop
271-
nop
272-
lea eax, [rdi+2]
273-
ret
274-
",
275-
options(noreturn)
276-
);
277-
}
260+
naked_asm!(
261+
"
262+
nop
263+
nop
264+
nop
265+
nop
266+
nop
267+
nop
268+
nop
269+
nop
270+
nop
271+
lea eax, [rdi+2]
272+
ret
273+
"
274+
);
278275
}
279276

280277
fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {

Diff for: tests/assembly/naked-functions/aarch64-naked-fn-no-bti-prolog.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use std::arch::naked_asm;
1313
// LLVM implements this via making sure of that, even for functions with the naked attribute.
1414
// So, we must emit an appropriate instruction instead!
1515
#[no_mangle]
16-
#[naked]
17-
pub unsafe extern "C" fn _hlt() -> ! {
16+
#[unsafe(naked)]
17+
pub extern "C" fn _hlt() -> ! {
1818
// CHECK-NOT: hint #34
1919
// CHECK: hlt #0x1
2020
naked_asm!("hlt #1")

Diff for: tests/assembly/naked-functions/aix.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use minicore::*;
2929
// CHECK-LABEL: blr:
3030
// CHECK: blr
3131
#[no_mangle]
32-
#[naked]
33-
unsafe extern "C" fn blr() {
32+
#[unsafe(naked)]
33+
extern "C" fn blr() {
3434
naked_asm!("blr")
3535
}

Diff for: tests/assembly/naked-functions/wasm32.rs

+30-30
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ use minicore::*;
2222
// CHECK-NOT: .size
2323
// CHECK: end_function
2424
#[no_mangle]
25-
#[naked]
26-
unsafe extern "C" fn nop() {
25+
#[unsafe(naked)]
26+
extern "C" fn nop() {
2727
naked_asm!("nop")
2828
}
2929

@@ -34,11 +34,11 @@ unsafe extern "C" fn nop() {
3434
// CHECK-NOT: .size
3535
// CHECK: end_function
3636
#[no_mangle]
37-
#[naked]
37+
#[unsafe(naked)]
3838
#[linkage = "weak"]
3939
// wasm functions cannot be aligned, so this has no effect
4040
#[repr(align(32))]
41-
unsafe extern "C" fn weak_aligned_nop() {
41+
extern "C" fn weak_aligned_nop() {
4242
naked_asm!("nop")
4343
}
4444

@@ -51,48 +51,48 @@ unsafe extern "C" fn weak_aligned_nop() {
5151
//
5252
// CHECK-NEXT: end_function
5353
#[no_mangle]
54-
#[naked]
55-
unsafe extern "C" fn fn_i8_i8(num: i8) -> i8 {
54+
#[unsafe(naked)]
55+
extern "C" fn fn_i8_i8(num: i8) -> i8 {
5656
naked_asm!("local.get 0", "local.get 0", "i32.mul")
5757
}
5858

5959
// CHECK-LABEL: fn_i8_i8_i8:
6060
// CHECK: .functype fn_i8_i8_i8 (i32, i32) -> (i32)
6161
#[no_mangle]
62-
#[naked]
63-
unsafe extern "C" fn fn_i8_i8_i8(a: i8, b: i8) -> i8 {
62+
#[unsafe(naked)]
63+
extern "C" fn fn_i8_i8_i8(a: i8, b: i8) -> i8 {
6464
naked_asm!("local.get 1", "local.get 0", "i32.mul")
6565
}
6666

6767
// CHECK-LABEL: fn_unit_i8:
6868
// CHECK: .functype fn_unit_i8 () -> (i32)
6969
#[no_mangle]
70-
#[naked]
71-
unsafe extern "C" fn fn_unit_i8() -> i8 {
70+
#[unsafe(naked)]
71+
extern "C" fn fn_unit_i8() -> i8 {
7272
naked_asm!("i32.const 42")
7373
}
7474

7575
// CHECK-LABEL: fn_i8_unit:
7676
// CHECK: .functype fn_i8_unit (i32) -> ()
7777
#[no_mangle]
78-
#[naked]
79-
unsafe extern "C" fn fn_i8_unit(_: i8) {
78+
#[unsafe(naked)]
79+
extern "C" fn fn_i8_unit(_: i8) {
8080
naked_asm!("nop")
8181
}
8282

8383
// CHECK-LABEL: fn_i32_i32:
8484
// CHECK: .functype fn_i32_i32 (i32) -> (i32)
8585
#[no_mangle]
86-
#[naked]
87-
unsafe extern "C" fn fn_i32_i32(num: i32) -> i32 {
86+
#[unsafe(naked)]
87+
extern "C" fn fn_i32_i32(num: i32) -> i32 {
8888
naked_asm!("local.get 0", "local.get 0", "i32.mul")
8989
}
9090

9191
// CHECK-LABEL: fn_i64_i64:
9292
// CHECK: .functype fn_i64_i64 (i64) -> (i64)
9393
#[no_mangle]
94-
#[naked]
95-
unsafe extern "C" fn fn_i64_i64(num: i64) -> i64 {
94+
#[unsafe(naked)]
95+
extern "C" fn fn_i64_i64(num: i64) -> i64 {
9696
naked_asm!("local.get 0", "local.get 0", "i64.mul")
9797
}
9898

@@ -101,8 +101,8 @@ unsafe extern "C" fn fn_i64_i64(num: i64) -> i64 {
101101
// wasm64-unknown: .functype fn_i128_i128 (i64, i64, i64) -> ()
102102
#[allow(improper_ctypes_definitions)]
103103
#[no_mangle]
104-
#[naked]
105-
unsafe extern "C" fn fn_i128_i128(num: i128) -> i128 {
104+
#[unsafe(naked)]
105+
extern "C" fn fn_i128_i128(num: i128) -> i128 {
106106
naked_asm!(
107107
"local.get 0",
108108
"local.get 2",
@@ -117,8 +117,8 @@ unsafe extern "C" fn fn_i128_i128(num: i128) -> i128 {
117117
// wasm32-wasip1: .functype fn_f128_f128 (i32, i64, i64) -> ()
118118
// wasm64-unknown: .functype fn_f128_f128 (i64, i64, i64) -> ()
119119
#[no_mangle]
120-
#[naked]
121-
unsafe extern "C" fn fn_f128_f128(num: f128) -> f128 {
120+
#[unsafe(naked)]
121+
extern "C" fn fn_f128_f128(num: f128) -> f128 {
122122
naked_asm!(
123123
"local.get 0",
124124
"local.get 2",
@@ -139,8 +139,8 @@ struct Compound {
139139
// wasm32-wasip1: .functype fn_compound_compound (i32, i32) -> ()
140140
// wasm64-unknown: .functype fn_compound_compound (i64, i64) -> ()
141141
#[no_mangle]
142-
#[naked]
143-
unsafe extern "C" fn fn_compound_compound(_: Compound) -> Compound {
142+
#[unsafe(naked)]
143+
extern "C" fn fn_compound_compound(_: Compound) -> Compound {
144144
// this is the wasm32-wasip1 assembly
145145
naked_asm!(
146146
"local.get 0",
@@ -160,8 +160,8 @@ struct WrapperI32(i32);
160160
// CHECK-LABEL: fn_wrapperi32_wrapperi32:
161161
// CHECK: .functype fn_wrapperi32_wrapperi32 (i32) -> (i32)
162162
#[no_mangle]
163-
#[naked]
164-
unsafe extern "C" fn fn_wrapperi32_wrapperi32(_: WrapperI32) -> WrapperI32 {
163+
#[unsafe(naked)]
164+
extern "C" fn fn_wrapperi32_wrapperi32(_: WrapperI32) -> WrapperI32 {
165165
naked_asm!("local.get 0")
166166
}
167167

@@ -171,8 +171,8 @@ struct WrapperI64(i64);
171171
// CHECK-LABEL: fn_wrapperi64_wrapperi64:
172172
// CHECK: .functype fn_wrapperi64_wrapperi64 (i64) -> (i64)
173173
#[no_mangle]
174-
#[naked]
175-
unsafe extern "C" fn fn_wrapperi64_wrapperi64(_: WrapperI64) -> WrapperI64 {
174+
#[unsafe(naked)]
175+
extern "C" fn fn_wrapperi64_wrapperi64(_: WrapperI64) -> WrapperI64 {
176176
naked_asm!("local.get 0")
177177
}
178178

@@ -182,8 +182,8 @@ struct WrapperF32(f32);
182182
// CHECK-LABEL: fn_wrapperf32_wrapperf32:
183183
// CHECK: .functype fn_wrapperf32_wrapperf32 (f32) -> (f32)
184184
#[no_mangle]
185-
#[naked]
186-
unsafe extern "C" fn fn_wrapperf32_wrapperf32(_: WrapperF32) -> WrapperF32 {
185+
#[unsafe(naked)]
186+
extern "C" fn fn_wrapperf32_wrapperf32(_: WrapperF32) -> WrapperF32 {
187187
naked_asm!("local.get 0")
188188
}
189189

@@ -193,7 +193,7 @@ struct WrapperF64(f64);
193193
// CHECK-LABEL: fn_wrapperf64_wrapperf64:
194194
// CHECK: .functype fn_wrapperf64_wrapperf64 (f64) -> (f64)
195195
#[no_mangle]
196-
#[naked]
197-
unsafe extern "C" fn fn_wrapperf64_wrapperf64(_: WrapperF64) -> WrapperF64 {
196+
#[unsafe(naked)]
197+
extern "C" fn fn_wrapperf64_wrapperf64(_: WrapperF64) -> WrapperF64 {
198198
naked_asm!("local.get 0")
199199
}

Diff for: tests/assembly/naked-functions/x86_64-naked-fn-no-cet-prolog.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ use std::arch::naked_asm;
1313
// works by using an instruction for each possible landing site,
1414
// and LLVM implements this via making sure of that.
1515
#[no_mangle]
16-
#[naked]
17-
pub unsafe extern "sysv64" fn will_halt() -> ! {
16+
#[unsafe(naked)]
17+
pub extern "sysv64" fn will_halt() -> ! {
1818
// CHECK-NOT: endbr{{32|64}}
1919
// CHECK: hlt
2020
naked_asm!("hlt")

Diff for: tests/codegen/cffi/c-variadic-naked.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88
#![feature(naked_functions)]
99
#![no_std]
1010

11-
#[naked]
11+
#[unsafe(naked)]
1212
pub unsafe extern "C" fn c_variadic(_: usize, _: ...) {
1313
// CHECK-NOT: va_start
1414
// CHECK-NOT: alloca
15-
core::arch::naked_asm! {
16-
"ret",
17-
}
15+
core::arch::naked_asm!("ret")
1816
}

Diff for: tests/codegen/naked-asan.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ pub fn caller() {
1313
}
1414

1515
// CHECK: declare x86_intrcc void @page_fault_handler(ptr {{.*}}, i64{{.*}}){{.*}}#[[ATTRS:[0-9]+]]
16-
#[naked]
16+
#[unsafe(naked)]
1717
#[no_mangle]
1818
pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) {
19-
unsafe { core::arch::naked_asm!("ud2") };
19+
core::arch::naked_asm!("ud2")
2020
}
2121

2222
// CHECK: #[[ATTRS]] =

Diff for: tests/codegen/naked-fn/aligned.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use std::arch::naked_asm;
1010
// CHECK-LABEL: naked_empty:
1111
#[repr(align(16))]
1212
#[no_mangle]
13-
#[naked]
14-
pub unsafe extern "C" fn naked_empty() {
13+
#[unsafe(naked)]
14+
pub extern "C" fn naked_empty() {
1515
// CHECK: ret
16-
naked_asm!("ret");
16+
naked_asm!("ret")
1717
}

0 commit comments

Comments
 (0)