Skip to content

Stabilize naked_functions #134213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,9 @@ builtin_macros_multiple_defaults = multiple declared defaults
.suggestion = make `{$ident}` default
builtin_macros_naked_functions_testing_attribute =
cannot use `#[naked]` with testing attributes
cannot use `#[unsafe(naked)]` with testing attributes
.label = function marked with testing attribute here
.naked_attribute = `#[naked]` is incompatible with testing attributes
.naked_attribute = `#[unsafe(naked)]` is incompatible with testing attributes
builtin_macros_no_default_variant = `#[derive(Default)]` on enum with no `#[default]`
.label = this enum needs a unit variant marked with `#[default]`
Expand Down
17 changes: 3 additions & 14 deletions compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
#![feature(
no_core,
lang_items,
never_type,
linkage,
extern_types,
naked_functions,
thread_local,
repr_simd
)]
#![feature(no_core, lang_items, never_type, linkage, extern_types, thread_local, repr_simd)]
#![no_core]
#![allow(dead_code, non_camel_case_types, internal_features)]

Expand Down Expand Up @@ -387,11 +378,9 @@ global_asm! {
}

#[cfg(all(not(jit), target_arch = "x86_64"))]
#[naked]
#[unsafe(naked)]
extern "C" fn naked_test() {
unsafe {
naked_asm!("ret");
}
naked_asm!("ret")
}

#[repr(C)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0736.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Erroneous code example:

```compile_fail,E0736
#[inline]
#[naked]
#[unsafe(naked)]
fn foo() {}
```

Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_error_codes/src/error_codes/E0787.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ An unsupported naked function definition.
Erroneous code example:

```compile_fail,E0787
#![feature(naked_functions)]

#[naked]
#[unsafe(naked)]
pub extern "C" fn f() -> u32 {
42
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ declare_features! (
/// Allows patterns with concurrent by-move and by-ref bindings.
/// For example, you can write `Foo(a, ref b)` where `a` is by-move and `b` is by-ref.
(accepted, move_ref_pattern, "1.49.0", Some(68354)),
/// Allows using `#[naked]` on functions.
(accepted, naked_functions, "CURRENT_RUSTC_VERSION", Some(90957)),
/// Allows specifying modifiers in the link attribute: `#[link(modifiers = "...")]`
(accepted, native_link_modifiers, "1.61.0", Some(81490)),
/// Allows specifying the bundle link modifier
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
ungated!(unsafe(Edition2024) no_mangle, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),
ungated!(used, Normal, template!(Word, List: "compiler|linker"), WarnFollowing, EncodeCrossCrate::No),
ungated!(link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding, EncodeCrossCrate::Yes),
ungated!(unsafe naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No),

// Limits:
ungated!(
Expand Down Expand Up @@ -515,12 +516,6 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
// Unstable attributes:
// ==========================================================================

// Linking:
gated!(
naked, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No,
naked_functions, experimental!(naked)
),

// Testing:
gated!(
test_runner, CrateLevel, template!(List: "path"), ErrorFollowing,
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,8 +563,6 @@ declare_features! (
(unstable, must_not_suspend, "1.57.0", Some(83310)),
/// Allows `mut ref` and `mut ref mut` identifier patterns.
(incomplete, mut_ref, "1.79.0", Some(123076)),
/// Allows using `#[naked]` on functions.
(unstable, naked_functions, "1.9.0", Some(90957)),
/// Allows using `#[naked]` on `extern "Rust"` functions.
(unstable, naked_functions_rustic_abi, "CURRENT_RUSTC_VERSION", Some(138997)),
/// Allows using `#[target_feature(enable = "...")]` on `#[naked]` on functions.
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_mir_build/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,13 +564,17 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
}
}
ExprKind::InlineAsm(box InlineAsmExpr {
asm_macro: AsmMacro::Asm | AsmMacro::NakedAsm,
asm_macro: asm_macro @ (AsmMacro::Asm | AsmMacro::NakedAsm),
ref operands,
template: _,
options: _,
line_spans: _,
}) => {
self.requires_unsafe(expr.span, UseOfInlineAssembly);
// The `naked` attribute and the `naked_asm!` block form one atomic unit of
// unsafety, and `naked_asm!` does not itself need to be wrapped in an unsafe block.
if let AsmMacro::Asm = asm_macro {
self.requires_unsafe(expr.span, UseOfInlineAssembly);
}

// For inline asm, do not use `walk_expr`, since we want to handle the label block
// specially.
Expand Down
6 changes: 0 additions & 6 deletions compiler/rustc_parse/src/validate_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,6 @@ pub fn check_attribute_safety(psess: &ParseSess, safety: AttributeSafety, attr:
}
}
} else if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
// Allow (but don't require) `#[unsafe(naked)]` so that compiler-builtins can upgrade to it.
// FIXME(#139797): remove this special case when compiler-builtins has upgraded.
if attr.has_name(sym::naked) {
return;
}

psess.dcx().emit_err(errors::InvalidAttrUnsafe {
span: unsafe_span,
name: attr_item.path.clone(),
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -508,17 +508,17 @@ passes_must_use_no_effect =
`#[must_use]` has no effect when applied to {$article} {$target}
passes_naked_asm_outside_naked_fn =
the `naked_asm!` macro can only be used in functions marked with `#[naked]`
the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
passes_naked_functions_asm_block =
naked functions must contain a single `naked_asm!` invocation
.label_multiple_asm = multiple `naked_asm!` invocations are not allowed in naked functions
.label_non_asm = not allowed in naked functions
passes_naked_functions_incompatible_attribute =
attribute incompatible with `#[naked]`
.label = the `{$attr}` attribute is incompatible with `#[naked]`
.naked_attribute = function marked with `#[naked]` here
attribute incompatible with `#[unsafe(naked)]`
.label = the `{$attr}` attribute is incompatible with `#[unsafe(naked)]`
.naked_attribute = function marked with `#[unsafe(naked)]` here
passes_naked_functions_must_naked_asm =
the `asm!` macro is not allowed in naked functions
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,13 +690,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
}
// FIXME(#80564): We permit struct fields, match arms and macro defs to have an
// `#[naked]` attribute with just a lint, because we previously
// erroneously allowed it and some crates used it accidentally, to be compatible
// with crates depending on them, we can't throw an error here.
Target::Field | Target::Arm | Target::MacroDef => {
self.inline_attr_str_error_with_macro_def(hir_id, attr, "naked")
}
_ => {
self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
attr_span: attr.span(),
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/arch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
///
/// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
#[unstable(feature = "naked_functions", issue = "90957")]
#[stable(feature = "naked_functions", since = "CURRENT_RUSTC_VERSION")]
#[rustc_builtin_macro]
pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
Expand Down
39 changes: 17 additions & 22 deletions src/doc/unstable-book/src/compiler-flags/sanitizer.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,36 +245,31 @@ See the [Clang ControlFlowIntegrity documentation][clang-cfi] for more details.
## Example 1: Redirecting control flow using an indirect branch/call to an invalid destination

```rust,ignore (making doc tests pass cross-platform is hard)
#![feature(naked_functions)]

use std::arch::asm;
use std::arch::naked_asm;
use std::mem;

fn add_one(x: i32) -> i32 {
x + 1
}

#[naked]
#[unsafe(naked)]
pub extern "C" fn add_two(x: i32) {
// x + 2 preceded by a landing pad/nop block
unsafe {
asm!(
"
nop
nop
nop
nop
nop
nop
nop
nop
nop
lea eax, [rdi+2]
ret
",
options(noreturn)
);
}
naked_asm!(
"
nop
nop
nop
nop
nop
nop
nop
nop
nop
lea eax, [rdi+2]
ret
"
);
}

fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//@ only-aarch64

#![crate_type = "lib"]
#![feature(naked_functions)]

use std::arch::naked_asm;

// The problem at hand: Rust has adopted a fairly strict meaning for "naked functions",
Expand All @@ -13,8 +13,8 @@ use std::arch::naked_asm;
// LLVM implements this via making sure of that, even for functions with the naked attribute.
// So, we must emit an appropriate instruction instead!
#[no_mangle]
#[naked]
pub unsafe extern "C" fn _hlt() -> ! {
#[unsafe(naked)]
pub extern "C" fn _hlt() -> ! {
// CHECK-NOT: hint #34
// CHECK: hlt #0x1
naked_asm!("hlt #1")
Expand Down
6 changes: 3 additions & 3 deletions tests/assembly/naked-functions/aix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//@[aix] needs-llvm-components: powerpc

#![crate_type = "lib"]
#![feature(no_core, naked_functions, asm_experimental_arch, f128, linkage, fn_align)]
#![feature(no_core, asm_experimental_arch, f128, linkage, fn_align)]
#![no_core]

// tests that naked functions work for the `powerpc64-ibm-aix` target.
Expand All @@ -29,7 +29,7 @@ use minicore::*;
// CHECK-LABEL: blr:
// CHECK: blr
#[no_mangle]
#[naked]
unsafe extern "C" fn blr() {
#[unsafe(naked)]
extern "C" fn blr() {
naked_asm!("blr")
}
Loading
Loading