disallow asm! in #[naked] functions

also disallow the `noreturn` option, and infer `naked_asm!` as `!`
This commit is contained in:
Folkert de Vries 2024-09-05 13:45:26 +02:00
parent 1a9c1cbf36
commit 562ec5a6fb
27 changed files with 223 additions and 298 deletions

View File

@ -2278,7 +2278,7 @@ impl InlineAsmOptions {
pub const COUNT: usize = Self::all().bits().count_ones() as usize; pub const COUNT: usize = Self::all().bits().count_ones() as usize;
pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW); pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW).union(Self::NORETURN); pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
pub fn human_readable_names(&self) -> Vec<&'static str> { pub fn human_readable_names(&self) -> Vec<&'static str> {
let mut options = vec![]; let mut options = vec![];
@ -2434,6 +2434,24 @@ pub enum AsmMacro {
NakedAsm, NakedAsm,
} }
impl AsmMacro {
pub const fn macro_name(&self) -> &'static str {
match self {
AsmMacro::Asm => "asm",
AsmMacro::GlobalAsm => "global_asm",
AsmMacro::NakedAsm => "naked_asm",
}
}
pub const fn is_supported_option(&self, option: InlineAsmOptions) -> bool {
match self {
AsmMacro::Asm => true,
AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
}
}
}
/// Inline assembly. /// Inline assembly.
/// ///
/// E.g., `asm!("NOP");`. /// E.g., `asm!("NOP");`.

View File

@ -60,35 +60,6 @@ fn eat_operand_keyword<'a>(
} }
} }
// Public for rustfmt consumption.
#[derive(Copy, Clone)]
pub enum AsmMacro {
/// The `asm!` macro
Asm,
/// The `global_asm!` macro
GlobalAsm,
/// The `naked_asm!` macro
NakedAsm,
}
impl AsmMacro {
const fn macro_name(&self) -> &'static str {
match self {
AsmMacro::Asm => "asm",
AsmMacro::GlobalAsm => "global_asm",
AsmMacro::NakedAsm => "naked_asm",
}
}
const fn is_supported_option(&self, option: ast::InlineAsmOptions) -> bool {
match self {
AsmMacro::Asm => true,
AsmMacro::GlobalAsm => ast::InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
AsmMacro::NakedAsm => ast::InlineAsmOptions::NAKED_OPTIONS.contains(option),
}
}
}
fn parse_args<'a>( fn parse_args<'a>(
ecx: &ExtCtxt<'a>, ecx: &ExtCtxt<'a>,
sp: Span, sp: Span,
@ -529,7 +500,7 @@ fn parse_reg<'a>(
fn expand_preparsed_asm( fn expand_preparsed_asm(
ecx: &mut ExtCtxt<'_>, ecx: &mut ExtCtxt<'_>,
asm_macro: ast::AsmMacro, asm_macro: AsmMacro,
args: AsmArgs, args: AsmArgs,
) -> ExpandResult<Result<ast::InlineAsm, ErrorGuaranteed>, ()> { ) -> ExpandResult<Result<ast::InlineAsm, ErrorGuaranteed>, ()> {
let mut template = vec![]; let mut template = vec![];
@ -872,7 +843,7 @@ pub(super) fn expand_naked_asm<'cx>(
sp: Span, sp: Span,
tts: TokenStream, tts: TokenStream,
) -> MacroExpanderResult<'cx> { ) -> MacroExpanderResult<'cx> {
ExpandResult::Ready(match parse_args(ecx, sp, tts, false) { ExpandResult::Ready(match parse_args(ecx, sp, tts, AsmMacro::NakedAsm) {
Ok(args) => { Ok(args) => {
let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, AsmMacro::NakedAsm, args) let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, AsmMacro::NakedAsm, args)
else { else {
@ -940,32 +911,3 @@ pub(super) fn expand_global_asm<'cx>(
} }
}) })
} }
pub(super) fn expand_naked_asm<'cx>(
ecx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> MacroExpanderResult<'cx> {
ExpandResult::Ready(match parse_args(ecx, sp, tts, AsmMacro::NakedAsm) {
Ok(args) => {
let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, args) else {
return ExpandResult::Retry(());
};
let expr = match mac {
Ok(inline_asm) => P(ast::Expr {
id: ast::DUMMY_NODE_ID,
kind: ast::ExprKind::InlineAsm(P(inline_asm)),
span: sp,
attrs: ast::AttrVec::new(),
tokens: None,
}),
Err(guar) => DummyResult::raw_expr(sp, Some(guar)),
};
MacEager::expr(expr)
}
Err(err) => {
let guar = err.emit();
DummyResult::any(sp, guar)
}
})
}

View File

@ -11,11 +11,10 @@ pub extern "C" fn f() -> u32 {
} }
``` ```
The naked functions must be defined using a single inline assembly The naked function must be defined using a single `naked_asm!` assembly block.
block.
The execution must never fall through past the end of the assembly The execution must never fall through past the end of the assembly
code so the block must use `noreturn` option. The asm block can also code, so it must either return or diverge. The asm block can also
use `att_syntax` and `raw` options, but others options are not allowed. use `att_syntax` and `raw` options, but others options are not allowed.
The asm block must not contain any operands other than `const` and The asm block must not contain any operands other than `const` and

View File

@ -3507,7 +3507,11 @@ fn check_expr_asm_operand(&self, expr: &'tcx hir::Expr<'tcx>, is_input: bool) {
} }
fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>) -> Ty<'tcx> { fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>) -> Ty<'tcx> {
let mut diverge = asm.options.contains(ast::InlineAsmOptions::NORETURN); let mut diverge = match asm.asm_macro {
rustc_ast::AsmMacro::Asm => asm.options.contains(ast::InlineAsmOptions::NORETURN),
rustc_ast::AsmMacro::GlobalAsm => true,
rustc_ast::AsmMacro::NakedAsm => true,
};
for (op, _op_sp) in asm.operands { for (op, _op_sp) in asm.operands {
match op { match op {

View File

@ -488,9 +488,9 @@ 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 `#[naked]`
passes_naked_functions_asm_block = passes_naked_functions_asm_block =
naked functions must contain a single asm block naked functions must contain a single `naked_asm!` invocation
.label_multiple_asm = multiple asm blocks are unsupported in naked functions .label_multiple_asm = multiple `naked_asm!` invocations are not allowed in naked functions
.label_non_asm = non-asm is unsupported in naked functions .label_non_asm = not allowed in naked functions
passes_naked_functions_asm_options = passes_naked_functions_asm_options =
asm options unsupported in naked functions: {$unsupported_options} asm options unsupported in naked functions: {$unsupported_options}
@ -500,9 +500,9 @@ passes_naked_functions_incompatible_attribute =
.label = the `{$attr}` attribute is incompatible with `#[naked]` .label = the `{$attr}` attribute is incompatible with `#[naked]`
.naked_attribute = function marked with `#[naked]` here .naked_attribute = function marked with `#[naked]` here
passes_naked_functions_must_use_noreturn = passes_naked_functions_must_naked_asm =
asm in naked functions must use `noreturn` option the `asm!` macro is not allowed in naked functions
.suggestion = consider specifying that the asm block is responsible for returning from the function .suggestion = consider using the `naked_asm!` macro instead
passes_naked_functions_operands = passes_naked_functions_operands =
only `const` and `sym` operands are supported in naked functions only `const` and `sym` operands are supported in naked functions

View File

@ -1202,12 +1202,12 @@ pub(crate) struct NakedFunctionsAsmOptions {
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(passes_naked_functions_must_use_noreturn, code = E0787)] #[diag(passes_naked_functions_must_naked_asm, code = E0787)]
pub(crate) struct NakedFunctionsMustUseNoreturn { pub(crate) struct NakedFunctionsMustNakedAsm {
#[primary_span] #[primary_span]
pub span: Span, pub span: Span,
#[suggestion(code = ", options(noreturn)", applicability = "machine-applicable")] #[suggestion(code = "naked_asm!", applicability = "machine-applicable")]
pub last_span: Span, pub macro_span: Span,
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]

View File

@ -10,13 +10,13 @@
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI; use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI;
use rustc_span::Span;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::{BytePos, Span};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use crate::errors::{ use crate::errors::{
NakedAsmOutsideNakedFn, NakedFunctionsAsmBlock, NakedFunctionsAsmOptions, NakedAsmOutsideNakedFn, NakedFunctionsAsmBlock, NakedFunctionsAsmOptions,
NakedFunctionsMustUseNoreturn, NakedFunctionsOperands, NoPatterns, ParamsNotAllowed, NakedFunctionsMustNakedAsm, NakedFunctionsOperands, NoPatterns, ParamsNotAllowed,
UndefinedNakedFunctionAbi, UndefinedNakedFunctionAbi,
}; };
@ -121,21 +121,29 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<'tcx>) { fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<'tcx>) {
let mut this = CheckInlineAssembly { tcx, items: Vec::new() }; let mut this = CheckInlineAssembly { tcx, items: Vec::new() };
this.visit_body(body); this.visit_body(body);
if let [(ItemKind::Asm | ItemKind::Err, _)] = this.items[..] { if let [(ItemKind::NakedAsm | ItemKind::Err, _)] = this.items[..] {
// Ok. // Ok.
} else { } else {
let mut must_show_error = false; let mut must_show_error = false;
let mut has_asm = false; let mut has_naked_asm = false;
let mut has_err = false; let mut has_err = false;
let mut multiple_asms = vec![]; let mut multiple_asms = vec![];
let mut non_asms = vec![]; let mut non_asms = vec![];
for &(kind, span) in &this.items { for &(kind, span) in &this.items {
match kind { match kind {
ItemKind::Asm if has_asm => { ItemKind::NakedAsm if has_naked_asm => {
must_show_error = true; must_show_error = true;
multiple_asms.push(span); multiple_asms.push(span);
} }
ItemKind::Asm => has_asm = true, ItemKind::NakedAsm => has_naked_asm = true,
ItemKind::InlineAsm => {
has_err = true;
// the span that contains the `asm!` call,
// so tooling can replace it with `naked_asm!`
let macro_span = span.with_hi(span.lo() + BytePos("asm!".len() as u32));
tcx.dcx().emit_err(NakedFunctionsMustNakedAsm { span, macro_span });
}
ItemKind::NonAsm => { ItemKind::NonAsm => {
must_show_error = true; must_show_error = true;
non_asms.push(span); non_asms.push(span);
@ -164,7 +172,8 @@ struct CheckInlineAssembly<'tcx> {
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
enum ItemKind { enum ItemKind {
Asm, NakedAsm,
InlineAsm,
NonAsm, NonAsm,
Err, Err,
} }
@ -205,8 +214,18 @@ fn check_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, span: Span) {
} }
ExprKind::InlineAsm(asm) => { ExprKind::InlineAsm(asm) => {
self.items.push((ItemKind::Asm, span)); match asm.asm_macro {
self.check_inline_asm(asm, span); rustc_ast::AsmMacro::Asm => {
self.items.push((ItemKind::InlineAsm, span));
}
rustc_ast::AsmMacro::NakedAsm => {
self.items.push((ItemKind::NakedAsm, span));
self.check_inline_asm(asm, span);
}
rustc_ast::AsmMacro::GlobalAsm => {
// not allowed in this position
}
}
} }
ExprKind::DropTemps(..) | ExprKind::Block(..) => { ExprKind::DropTemps(..) | ExprKind::Block(..) => {
@ -250,16 +269,6 @@ fn check_inline_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) {
.join(", "), .join(", "),
}); });
} }
if !asm.options.contains(InlineAsmOptions::NORETURN) {
let last_span = asm
.operands
.last()
.map_or_else(|| asm.template_strs.last().unwrap().2, |op| op.1)
.shrink_to_hi();
self.tcx.dcx().emit_err(NakedFunctionsMustUseNoreturn { span, last_span });
}
} }
} }

View File

@ -77,17 +77,3 @@ macro_rules! naked_asm {
pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) { pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */ /* compiler built-in */
} }
/// Inline assembly used in combination with `#[naked]` functions.
///
/// Refer to [Rust By Example] for a usage guide and the [reference] for
/// detailed information about the syntax and available options.
///
/// [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")]
#[rustc_builtin_macro]
#[cfg(not(bootstrap))]
pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
}

View File

@ -1,5 +1,5 @@
use rustc_ast::ast; use rustc_ast::ast;
use rustc_builtin_macros::asm::{parse_asm_args, AsmArgs, AsmMacro}; use rustc_builtin_macros::asm::{parse_asm_args, AsmArgs};
use crate::rewrite::RewriteContext; use crate::rewrite::RewriteContext;
@ -7,5 +7,5 @@
pub(crate) fn parse_asm(context: &RewriteContext<'_>, mac: &ast::MacCall) -> Option<AsmArgs> { pub(crate) fn parse_asm(context: &RewriteContext<'_>, mac: &ast::MacCall) -> Option<AsmArgs> {
let ts = mac.args.tokens.clone(); let ts = mac.args.tokens.clone();
let mut parser = super::build_parser(context, ts); let mut parser = super::build_parser(context, ts);
parse_asm_args(&mut parser, mac.span(), AsmMacro::Asm).ok() parse_asm_args(&mut parser, mac.span(), ast::AsmMacro::Asm).ok()
} }

View File

@ -4,7 +4,7 @@
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(naked_functions, fn_align)] #![feature(naked_functions, fn_align)]
use std::arch::asm; use std::arch::naked_asm;
// CHECK: Function Attrs: naked // CHECK: Function Attrs: naked
// CHECK-NEXT: define{{.*}}void @naked_empty() // CHECK-NEXT: define{{.*}}void @naked_empty()
@ -16,5 +16,5 @@
// CHECK-NEXT: start: // CHECK-NEXT: start:
// CHECK-NEXT: call void asm // CHECK-NEXT: call void asm
// CHECK-NEXT: unreachable // CHECK-NEXT: unreachable
asm!("ret", options(noreturn)); naked_asm!("ret");
} }

View File

@ -14,7 +14,7 @@
// CHECK-NEXT: {{.+}}: // CHECK-NEXT: {{.+}}:
// CHECK-NEXT: call void asm // CHECK-NEXT: call void asm
// CHECK-NEXT: unreachable // CHECK-NEXT: unreachable
naked_asm!("ret", options(noreturn)); naked_asm!("ret");
} }
// CHECK: Function Attrs: naked // CHECK: Function Attrs: naked
@ -25,5 +25,5 @@
// CHECK-NEXT: {{.+}}: // CHECK-NEXT: {{.+}}:
// CHECK-NEXT: call void asm // CHECK-NEXT: call void asm
// CHECK-NEXT: unreachable // CHECK-NEXT: unreachable
naked_asm!("lea rax, [rdi + rsi]", "ret", options(noreturn)); naked_asm!("lea rax, [rdi + rsi]", "ret");
} }

View File

@ -6,7 +6,7 @@
//@ compile-flags: -Cinstrument-coverage //@ compile-flags: -Cinstrument-coverage
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(naked_functions)] #![feature(naked_functions)]
use std::arch::asm; use std::arch::naked_asm;
#[naked] #[naked]
#[no_mangle] #[no_mangle]
@ -15,5 +15,5 @@
// CHECK-NEXT: start: // CHECK-NEXT: start:
// CHECK-NEXT: call void asm // CHECK-NEXT: call void asm
// CHECK-NEXT: unreachable // CHECK-NEXT: unreachable
asm!("", options(noreturn)); naked_asm!("");
} }

View File

@ -5,7 +5,7 @@
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(naked_functions)] #![feature(naked_functions)]
use std::arch::asm; use std::arch::naked_asm;
#[naked] #[naked]
#[no_mangle] #[no_mangle]
@ -15,7 +15,7 @@
// CHECK: define {{(dso_local )?}}void @f() unnamed_addr [[ATTR:#[0-9]+]] // CHECK: define {{(dso_local )?}}void @f() unnamed_addr [[ATTR:#[0-9]+]]
// CHECK-NEXT: start: // CHECK-NEXT: start:
// CHECK-NEXT: call void asm // CHECK-NEXT: call void asm
asm!("", options(noreturn)); naked_asm!("");
} }
#[no_mangle] #[no_mangle]

View File

@ -10,6 +10,6 @@ pub extern "C" fn naked(p: char) -> u128 {
//~^ WARN uses type `char` //~^ WARN uses type `char`
//~| WARN uses type `u128` //~| WARN uses type `u128`
unsafe { unsafe {
naked_asm!("", options(noreturn)); naked_asm!("");
} }
} }

View File

@ -19,7 +19,7 @@
#[naked] #[naked]
#[inline(always)] #[inline(always)]
//~^ ERROR [E0736] //~^ ERROR [E0736]
<<<<<<< HEAD pub unsafe extern "C" fn inline_always() {
naked_asm!(""); naked_asm!("");
} }

View File

@ -19,12 +19,12 @@ trait Sized {}
#[naked] #[naked]
#[instruction_set(arm::t32)] #[instruction_set(arm::t32)]
unsafe extern "C" fn test_thumb() { unsafe extern "C" fn test_thumb() {
naked_asm!("bx lr", options(noreturn)); naked_asm!("bx lr");
} }
#[no_mangle] #[no_mangle]
#[naked] #[naked]
#[instruction_set(arm::t32)] #[instruction_set(arm::t32)]
unsafe extern "C" fn test_arm() { unsafe extern "C" fn test_arm() {
naked_asm!("bx lr", options(noreturn)); naked_asm!("bx lr");
} }

View File

@ -12,7 +12,7 @@
#[naked] #[naked]
//~^ ERROR [E0736] //~^ ERROR [E0736]
fn test_naked() { fn test_naked() {
unsafe { naked_asm!("", options(noreturn)) }; unsafe { naked_asm!("") };
} }
#[should_panic] #[should_panic]
@ -20,7 +20,7 @@ fn test_naked() {
#[naked] #[naked]
//~^ ERROR [E0736] //~^ ERROR [E0736]
fn test_naked_should_panic() { fn test_naked_should_panic() {
unsafe { naked_asm!("", options(noreturn)) }; unsafe { naked_asm!("") };
} }
#[ignore] #[ignore]
@ -28,12 +28,12 @@ fn test_naked_should_panic() {
#[naked] #[naked]
//~^ ERROR [E0736] //~^ ERROR [E0736]
fn test_naked_ignore() { fn test_naked_ignore() {
unsafe { naked_asm!("", options(noreturn)) }; unsafe { naked_asm!("") };
} }
#[bench] #[bench]
#[naked] #[naked]
//~^ ERROR [E0736] //~^ ERROR [E0736]
fn bench_naked() { fn bench_naked() {
unsafe { naked_asm!("", options(noreturn)) }; unsafe { naked_asm!("") };
} }

View File

@ -67,7 +67,7 @@ pub mod naked {
#[naked] #[naked]
pub extern "C" fn function(a: usize, b: usize) -> usize { pub extern "C" fn function(a: usize, b: usize) -> usize {
unsafe { unsafe {
naked_asm!("", options(noreturn)); naked_asm!("");
} }
} }
@ -77,14 +77,14 @@ impl Naked {
#[naked] #[naked]
pub extern "C" fn associated(a: usize, b: usize) -> usize { pub extern "C" fn associated(a: usize, b: usize) -> usize {
unsafe { unsafe {
naked_asm!("", options(noreturn)); naked_asm!("");
} }
} }
#[naked] #[naked]
pub extern "C" fn method(&self, a: usize, b: usize) -> usize { pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
unsafe { unsafe {
naked_asm!("", options(noreturn)); naked_asm!("");
} }
} }
} }
@ -93,14 +93,14 @@ impl super::Trait for Naked {
#[naked] #[naked]
extern "C" fn trait_associated(a: usize, b: usize) -> usize { extern "C" fn trait_associated(a: usize, b: usize) -> usize {
unsafe { unsafe {
naked_asm!("", options(noreturn)); naked_asm!("");
} }
} }
#[naked] #[naked]
extern "C" fn trait_method(&self, a: usize, b: usize) -> usize { extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
unsafe { unsafe {
naked_asm!("", options(noreturn)); naked_asm!("");
} }
} }
} }

View File

@ -6,7 +6,13 @@
#![feature(asm_unwind, linkage)] #![feature(asm_unwind, linkage)]
#![crate_type = "lib"] #![crate_type = "lib"]
use std::arch::naked_asm; use std::arch::{asm, naked_asm};
#[naked]
pub unsafe extern "C" fn inline_asm_macro() {
asm!("", options(raw));
//~^ERROR the `asm!` macro is not allowed in naked functions
}
#[repr(C)] #[repr(C)]
pub struct P { pub struct P {
@ -25,12 +31,12 @@ pub struct P {
P { x, y }: P, P { x, y }: P,
//~^ ERROR patterns not allowed in naked function parameters //~^ ERROR patterns not allowed in naked function parameters
) { ) {
naked_asm!("", options(noreturn)) naked_asm!("")
} }
#[naked] #[naked]
pub unsafe extern "C" fn inc(a: u32) -> u32 { pub unsafe extern "C" fn inc(a: u32) -> u32 {
//~^ ERROR naked functions must contain a single asm block //~^ ERROR naked functions must contain a single `naked_asm!` invocation
a + 1 a + 1
//~^ ERROR referencing function parameters is not allowed in naked functions //~^ ERROR referencing function parameters is not allowed in naked functions
} }
@ -38,19 +44,19 @@ pub struct P {
#[naked] #[naked]
#[allow(asm_sub_register)] #[allow(asm_sub_register)]
pub unsafe extern "C" fn inc_asm(a: u32) -> u32 { pub unsafe extern "C" fn inc_asm(a: u32) -> u32 {
naked_asm!("/* {0} */", in(reg) a, options(noreturn)) naked_asm!("/* {0} */", in(reg) a)
//~^ ERROR the `in` operand cannot be used with `naked_asm!` //~^ ERROR the `in` operand cannot be used with `naked_asm!`
} }
#[naked] #[naked]
pub unsafe extern "C" fn inc_closure(a: u32) -> u32 { pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
//~^ ERROR naked functions must contain a single asm block //~^ ERROR naked functions must contain a single `naked_asm!` invocation
(|| a + 1)() (|| a + 1)()
} }
#[naked] #[naked]
pub unsafe extern "C" fn unsupported_operands() { pub unsafe extern "C" fn unsupported_operands() {
//~^ ERROR naked functions must contain a single asm block //~^ ERROR naked functions must contain a single `naked_asm!` invocation
let mut a = 0usize; let mut a = 0usize;
let mut b = 0usize; let mut b = 0usize;
let mut c = 0usize; let mut c = 0usize;
@ -72,27 +78,23 @@ pub struct P {
#[naked] #[naked]
pub extern "C" fn missing_assembly() { pub extern "C" fn missing_assembly() {
//~^ ERROR naked functions must contain a single asm block //~^ ERROR naked functions must contain a single `naked_asm!` invocation
} }
#[naked] #[naked]
pub extern "C" fn too_many_asm_blocks() { pub extern "C" fn too_many_asm_blocks() {
//~^ ERROR naked functions must contain a single asm block //~^ ERROR naked functions must contain a single `naked_asm!` invocation
unsafe { unsafe {
naked_asm!("");
//~^ ERROR asm in naked functions must use `noreturn` option
naked_asm!("");
//~^ ERROR asm in naked functions must use `noreturn` option
naked_asm!("");
//~^ ERROR asm in naked functions must use `noreturn` option
naked_asm!("", options(noreturn)); naked_asm!("", options(noreturn));
//~^ ERROR the `noreturn` option cannot be used with `naked_asm!`
naked_asm!("");
} }
} }
pub fn outer(x: u32) -> extern "C" fn(usize) -> usize { pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
#[naked] #[naked]
pub extern "C" fn inner(y: usize) -> usize { pub extern "C" fn inner(y: usize) -> usize {
//~^ ERROR naked functions must contain a single asm block //~^ ERROR naked functions must contain a single `naked_asm!` invocation
*&y *&y
//~^ ERROR referencing function parameters is not allowed in naked functions //~^ ERROR referencing function parameters is not allowed in naked functions
} }
@ -101,7 +103,7 @@ pub extern "C" fn inner(y: usize) -> usize {
#[naked] #[naked]
unsafe extern "C" fn invalid_options() { unsafe extern "C" fn invalid_options() {
naked_asm!("", options(nomem, preserves_flags, noreturn)); naked_asm!("", options(nomem, preserves_flags));
//~^ ERROR the `nomem` option cannot be used with `naked_asm!` //~^ ERROR the `nomem` option cannot be used with `naked_asm!`
//~| ERROR the `preserves_flags` option cannot be used with `naked_asm!` //~| ERROR the `preserves_flags` option cannot be used with `naked_asm!`
} }
@ -112,31 +114,30 @@ pub extern "C" fn inner(y: usize) -> usize {
//~^ ERROR the `readonly` option cannot be used with `naked_asm!` //~^ ERROR the `readonly` option cannot be used with `naked_asm!`
//~| ERROR the `nostack` option cannot be used with `naked_asm!` //~| ERROR the `nostack` option cannot be used with `naked_asm!`
//~| ERROR the `pure` option cannot be used with `naked_asm!` //~| ERROR the `pure` option cannot be used with `naked_asm!`
//~| ERROR asm in naked functions must use `noreturn` option
} }
#[naked] #[naked]
unsafe extern "C" fn invalid_may_unwind() { unsafe extern "C" fn invalid_may_unwind() {
naked_asm!("", options(noreturn, may_unwind)); naked_asm!("", options(may_unwind));
//~^ ERROR the `may_unwind` option cannot be used with `naked_asm!` //~^ ERROR the `may_unwind` option cannot be used with `naked_asm!`
} }
#[naked] #[naked]
pub unsafe fn default_abi() { pub unsafe fn default_abi() {
//~^ WARN Rust ABI is unsupported in naked functions //~^ WARN Rust ABI is unsupported in naked functions
naked_asm!("", options(noreturn)); naked_asm!("");
} }
#[naked] #[naked]
pub unsafe fn rust_abi() { pub unsafe fn rust_abi() {
//~^ WARN Rust ABI is unsupported in naked functions //~^ WARN Rust ABI is unsupported in naked functions
naked_asm!("", options(noreturn)); naked_asm!("");
} }
#[naked] #[naked]
pub extern "C" fn valid_a<T>() -> T { pub extern "C" fn valid_a<T>() -> T {
unsafe { unsafe {
naked_asm!("", options(noreturn)); naked_asm!("");
} }
} }
@ -145,7 +146,7 @@ pub extern "C" fn valid_b() {
unsafe { unsafe {
{ {
{ {
naked_asm!("", options(noreturn)); naked_asm!("");
}; };
}; };
} }
@ -153,13 +154,13 @@ pub extern "C" fn valid_b() {
#[naked] #[naked]
pub unsafe extern "C" fn valid_c() { pub unsafe extern "C" fn valid_c() {
naked_asm!("", options(noreturn)); naked_asm!("");
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
#[naked] #[naked]
pub unsafe extern "C" fn valid_att_syntax() { pub unsafe extern "C" fn valid_att_syntax() {
naked_asm!("", options(noreturn, att_syntax)); naked_asm!("", options(att_syntax));
} }
#[naked] #[naked]
@ -173,7 +174,7 @@ pub extern "C" fn valid_b() {
pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 { pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 {
compile_error!("this is a user specified error"); compile_error!("this is a user specified error");
//~^ ERROR this is a user specified error //~^ ERROR this is a user specified error
naked_asm!("", options(noreturn)) naked_asm!("")
} }
#[naked] #[naked]
@ -186,7 +187,7 @@ pub extern "C" fn valid_b() {
#[cfg_attr(target_pointer_width = "64", no_mangle)] #[cfg_attr(target_pointer_width = "64", no_mangle)]
#[naked] #[naked]
pub unsafe extern "C" fn compatible_cfg_attributes() { pub unsafe extern "C" fn compatible_cfg_attributes() {
naked_asm!("", options(noreturn, att_syntax)); naked_asm!("", options(att_syntax));
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -195,13 +196,13 @@ pub extern "C" fn valid_b() {
#[forbid(dead_code)] #[forbid(dead_code)]
#[naked] #[naked]
pub unsafe extern "C" fn compatible_diagnostic_attributes() { pub unsafe extern "C" fn compatible_diagnostic_attributes() {
naked_asm!("", options(noreturn, raw)); naked_asm!("", options(raw));
} }
#[deprecated = "test"] #[deprecated = "test"]
#[naked] #[naked]
pub unsafe extern "C" fn compatible_deprecated_attributes() { pub unsafe extern "C" fn compatible_deprecated_attributes() {
naked_asm!("", options(noreturn, raw)); naked_asm!("", options(raw));
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
@ -213,7 +214,6 @@ pub extern "C" fn valid_b() {
mov rax, 42 mov rax, 42
ret ret
", ",
options(noreturn)
) )
} }
@ -222,20 +222,20 @@ pub extern "C" fn valid_b() {
#[no_mangle] #[no_mangle]
#[naked] #[naked]
pub unsafe extern "C" fn compatible_ffi_attributes_1() { pub unsafe extern "C" fn compatible_ffi_attributes_1() {
naked_asm!("", options(noreturn, raw)); naked_asm!("", options(raw));
} }
#[cold] #[cold]
#[naked] #[naked]
pub unsafe extern "C" fn compatible_codegen_attributes() { pub unsafe extern "C" fn compatible_codegen_attributes() {
naked_asm!("", options(noreturn, raw)); naked_asm!("", options(raw));
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
#[target_feature(enable = "sse2")] #[target_feature(enable = "sse2")]
#[naked] #[naked]
pub unsafe extern "C" fn compatible_target_feature() { pub unsafe extern "C" fn compatible_target_feature() {
naked_asm!("", options(noreturn)); naked_asm!("");
} }
#[doc = "foo bar baz"] #[doc = "foo bar baz"]
@ -244,11 +244,11 @@ pub extern "C" fn valid_b() {
#[doc(alias = "ADocAlias")] #[doc(alias = "ADocAlias")]
#[naked] #[naked]
pub unsafe extern "C" fn compatible_doc_attributes() { pub unsafe extern "C" fn compatible_doc_attributes() {
naked_asm!("", options(noreturn, raw)); naked_asm!("", options(raw));
} }
#[linkage = "external"] #[linkage = "external"]
#[naked] #[naked]
pub unsafe extern "C" fn compatible_linkage() { pub unsafe extern "C" fn compatible_linkage() {
naked_asm!("", options(noreturn, raw)); naked_asm!("", options(raw));
} }

View File

@ -1,220 +1,184 @@
error: the `in` operand cannot be used with `naked_asm!` error: the `in` operand cannot be used with `naked_asm!`
--> $DIR/naked-functions.rs:41:29 --> $DIR/naked-functions.rs:47:29
| |
LL | naked_asm!("/* {0} */", in(reg) a, options(noreturn)) LL | naked_asm!("/* {0} */", in(reg) a)
| ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it | ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it
error: the `in` operand cannot be used with `naked_asm!` error: the `in` operand cannot be used with `naked_asm!`
--> $DIR/naked-functions.rs:62:10 --> $DIR/naked-functions.rs:68:10
| |
LL | in(reg) a, LL | in(reg) a,
| ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it | ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it
error: the `nomem` option cannot be used with `naked_asm!` error: the `noreturn` option cannot be used with `naked_asm!`
--> $DIR/naked-functions.rs:104:28 --> $DIR/naked-functions.rs:88:32
| |
LL | naked_asm!("", options(nomem, preserves_flags, noreturn)); LL | naked_asm!("", options(noreturn));
| ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly
error: the `nomem` option cannot be used with `naked_asm!`
--> $DIR/naked-functions.rs:106:28
|
LL | naked_asm!("", options(nomem, preserves_flags));
| ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly | ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
error: the `preserves_flags` option cannot be used with `naked_asm!` error: the `preserves_flags` option cannot be used with `naked_asm!`
--> $DIR/naked-functions.rs:104:35 --> $DIR/naked-functions.rs:106:35
| |
LL | naked_asm!("", options(nomem, preserves_flags, noreturn)); LL | naked_asm!("", options(nomem, preserves_flags));
| ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly | ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly
error: the `readonly` option cannot be used with `naked_asm!` error: the `readonly` option cannot be used with `naked_asm!`
--> $DIR/naked-functions.rs:111:28 --> $DIR/naked-functions.rs:113:28
| |
LL | naked_asm!("", options(readonly, nostack), options(pure)); LL | naked_asm!("", options(readonly, nostack), options(pure));
| ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly | ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly
error: the `nostack` option cannot be used with `naked_asm!` error: the `nostack` option cannot be used with `naked_asm!`
--> $DIR/naked-functions.rs:111:38 --> $DIR/naked-functions.rs:113:38
| |
LL | naked_asm!("", options(readonly, nostack), options(pure)); LL | naked_asm!("", options(readonly, nostack), options(pure));
| ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly | ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly
error: the `pure` option cannot be used with `naked_asm!` error: the `pure` option cannot be used with `naked_asm!`
--> $DIR/naked-functions.rs:111:56 --> $DIR/naked-functions.rs:113:56
| |
LL | naked_asm!("", options(readonly, nostack), options(pure)); LL | naked_asm!("", options(readonly, nostack), options(pure));
| ^^^^ the `pure` option is not meaningful for global-scoped inline assembly | ^^^^ the `pure` option is not meaningful for global-scoped inline assembly
error: the `may_unwind` option cannot be used with `naked_asm!` error: the `may_unwind` option cannot be used with `naked_asm!`
--> $DIR/naked-functions.rs:120:38 --> $DIR/naked-functions.rs:121:28
| |
LL | naked_asm!("", options(noreturn, may_unwind)); LL | naked_asm!("", options(may_unwind));
| ^^^^^^^^^^ the `may_unwind` option is not meaningful for global-scoped inline assembly | ^^^^^^^^^^ the `may_unwind` option is not meaningful for global-scoped inline assembly
error: this is a user specified error error: this is a user specified error
--> $DIR/naked-functions.rs:168:5 --> $DIR/naked-functions.rs:169:5
| |
LL | compile_error!("this is a user specified error") LL | compile_error!("this is a user specified error")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: this is a user specified error error: this is a user specified error
--> $DIR/naked-functions.rs:174:5 --> $DIR/naked-functions.rs:175:5
| |
LL | compile_error!("this is a user specified error"); LL | compile_error!("this is a user specified error");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: asm template must be a string literal error: asm template must be a string literal
--> $DIR/naked-functions.rs:181:16 --> $DIR/naked-functions.rs:182:16
| |
LL | naked_asm!(invalid_syntax) LL | naked_asm!(invalid_syntax)
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error[E0787]: the `asm!` macro is not allowed in naked functions
--> $DIR/naked-functions.rs:13:5
|
LL | asm!("", options(raw));
| ----^^^^^^^^^^^^^^^^^^
| |
| help: consider using the `naked_asm!` macro instead: `naked_asm!`
error: patterns not allowed in naked function parameters error: patterns not allowed in naked function parameters
--> $DIR/naked-functions.rs:19:5 --> $DIR/naked-functions.rs:25:5
| |
LL | mut a: u32, LL | mut a: u32,
| ^^^^^ | ^^^^^
error: patterns not allowed in naked function parameters error: patterns not allowed in naked function parameters
--> $DIR/naked-functions.rs:21:5 --> $DIR/naked-functions.rs:27:5
| |
LL | &b: &i32, LL | &b: &i32,
| ^^ | ^^
error: patterns not allowed in naked function parameters error: patterns not allowed in naked function parameters
--> $DIR/naked-functions.rs:23:6 --> $DIR/naked-functions.rs:29:6
| |
LL | (None | Some(_)): Option<std::ptr::NonNull<u8>>, LL | (None | Some(_)): Option<std::ptr::NonNull<u8>>,
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: patterns not allowed in naked function parameters error: patterns not allowed in naked function parameters
--> $DIR/naked-functions.rs:25:5 --> $DIR/naked-functions.rs:31:5
| |
LL | P { x, y }: P, LL | P { x, y }: P,
| ^^^^^^^^^^ | ^^^^^^^^^^
error: referencing function parameters is not allowed in naked functions error: referencing function parameters is not allowed in naked functions
--> $DIR/naked-functions.rs:34:5 --> $DIR/naked-functions.rs:40:5
| |
LL | a + 1 LL | a + 1
| ^ | ^
| |
= help: follow the calling convention in asm block to use parameters = help: follow the calling convention in asm block to use parameters
error[E0787]: naked functions must contain a single asm block error[E0787]: naked functions must contain a single `naked_asm!` invocation
--> $DIR/naked-functions.rs:32:1 --> $DIR/naked-functions.rs:38:1
| |
LL | pub unsafe extern "C" fn inc(a: u32) -> u32 { LL | pub unsafe extern "C" fn inc(a: u32) -> u32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | LL |
LL | a + 1 LL | a + 1
| ----- non-asm is unsupported in naked functions | ----- not allowed in naked functions
error[E0787]: naked functions must contain a single asm block error[E0787]: naked functions must contain a single `naked_asm!` invocation
--> $DIR/naked-functions.rs:46:1 --> $DIR/naked-functions.rs:52:1
| |
LL | pub unsafe extern "C" fn inc_closure(a: u32) -> u32 { LL | pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | LL |
LL | (|| a + 1)() LL | (|| a + 1)()
| ------------ non-asm is unsupported in naked functions | ------------ not allowed in naked functions
error[E0787]: naked functions must contain a single asm block error[E0787]: naked functions must contain a single `naked_asm!` invocation
--> $DIR/naked-functions.rs:52:1 --> $DIR/naked-functions.rs:58:1
| |
LL | pub unsafe extern "C" fn unsupported_operands() { LL | pub unsafe extern "C" fn unsupported_operands() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | LL |
LL | let mut a = 0usize; LL | let mut a = 0usize;
| ------------------- non-asm is unsupported in naked functions | ------------------- not allowed in naked functions
LL | let mut b = 0usize; LL | let mut b = 0usize;
| ------------------- non-asm is unsupported in naked functions | ------------------- not allowed in naked functions
LL | let mut c = 0usize; LL | let mut c = 0usize;
| ------------------- non-asm is unsupported in naked functions | ------------------- not allowed in naked functions
LL | let mut d = 0usize; LL | let mut d = 0usize;
| ------------------- non-asm is unsupported in naked functions | ------------------- not allowed in naked functions
LL | let mut e = 0usize; LL | let mut e = 0usize;
| ------------------- non-asm is unsupported in naked functions | ------------------- not allowed in naked functions
error[E0787]: naked functions must contain a single asm block error[E0787]: naked functions must contain a single `naked_asm!` invocation
--> $DIR/naked-functions.rs:74:1 --> $DIR/naked-functions.rs:80:1
| |
LL | pub extern "C" fn missing_assembly() { LL | pub extern "C" fn missing_assembly() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0787]: asm in naked functions must use `noreturn` option error[E0787]: naked functions must contain a single `naked_asm!` invocation
--> $DIR/naked-functions.rs:82:9 --> $DIR/naked-functions.rs:85:1
|
LL | naked_asm!("");
| ^^^^^^^^^^^^^^
|
help: consider specifying that the asm block is responsible for returning from the function
|
LL | naked_asm!("", options(noreturn));
| +++++++++++++++++++
error[E0787]: asm in naked functions must use `noreturn` option
--> $DIR/naked-functions.rs:84:9
|
LL | naked_asm!("");
| ^^^^^^^^^^^^^^
|
help: consider specifying that the asm block is responsible for returning from the function
|
LL | naked_asm!("", options(noreturn));
| +++++++++++++++++++
error[E0787]: asm in naked functions must use `noreturn` option
--> $DIR/naked-functions.rs:86:9
|
LL | naked_asm!("");
| ^^^^^^^^^^^^^^
|
help: consider specifying that the asm block is responsible for returning from the function
|
LL | naked_asm!("", options(noreturn));
| +++++++++++++++++++
error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:79:1
| |
LL | pub extern "C" fn too_many_asm_blocks() { LL | pub extern "C" fn too_many_asm_blocks() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
... ...
LL | naked_asm!(""); LL | naked_asm!("");
| -------------- multiple asm blocks are unsupported in naked functions | -------------- multiple `naked_asm!` invocations are not allowed in naked functions
LL |
LL | naked_asm!("");
| -------------- multiple asm blocks are unsupported in naked functions
LL |
LL | naked_asm!("", options(noreturn));
| --------------------------------- multiple asm blocks are unsupported in naked functions
error: referencing function parameters is not allowed in naked functions error: referencing function parameters is not allowed in naked functions
--> $DIR/naked-functions.rs:96:11 --> $DIR/naked-functions.rs:98:11
| |
LL | *&y LL | *&y
| ^ | ^
| |
= help: follow the calling convention in asm block to use parameters = help: follow the calling convention in asm block to use parameters
error[E0787]: naked functions must contain a single asm block error[E0787]: naked functions must contain a single `naked_asm!` invocation
--> $DIR/naked-functions.rs:94:5 --> $DIR/naked-functions.rs:96:5
| |
LL | pub extern "C" fn inner(y: usize) -> usize { LL | pub extern "C" fn inner(y: usize) -> usize {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | LL |
LL | *&y LL | *&y
| --- non-asm is unsupported in naked functions | --- not allowed in naked functions
error[E0787]: asm in naked functions must use `noreturn` option
--> $DIR/naked-functions.rs:111:5
|
LL | naked_asm!("", options(readonly, nostack), options(pure));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider specifying that the asm block is responsible for returning from the function
|
LL | naked_asm!("", options(noreturn), options(readonly, nostack), options(pure));
| +++++++++++++++++++
warning: Rust ABI is unsupported in naked functions warning: Rust ABI is unsupported in naked functions
--> $DIR/naked-functions.rs:125:1 --> $DIR/naked-functions.rs:126:1
| |
LL | pub unsafe fn default_abi() { LL | pub unsafe fn default_abi() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -222,11 +186,11 @@ LL | pub unsafe fn default_abi() {
= note: `#[warn(undefined_naked_function_abi)]` on by default = note: `#[warn(undefined_naked_function_abi)]` on by default
warning: Rust ABI is unsupported in naked functions warning: Rust ABI is unsupported in naked functions
--> $DIR/naked-functions.rs:131:1 --> $DIR/naked-functions.rs:132:1
| |
LL | pub unsafe fn rust_abi() { LL | pub unsafe fn rust_abi() {
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 27 previous errors; 2 warnings emitted error: aborting due to 25 previous errors; 2 warnings emitted
For more information about this error, try `rustc --explain E0787`. For more information about this error, try `rustc --explain E0787`.

View File

@ -4,7 +4,7 @@
#![feature(naked_functions)] #![feature(naked_functions)]
#![naked] //~ ERROR should be applied to a function definition #![naked] //~ ERROR should be applied to a function definition
use std::arch::asm; use std::arch::naked_asm;
extern "C" { extern "C" {
#[naked] //~ ERROR should be applied to a function definition #[naked] //~ ERROR should be applied to a function definition
@ -26,27 +26,28 @@ trait Invoke {
impl Invoke for S { impl Invoke for S {
#[naked] #[naked]
extern "C" fn invoke(&self) { extern "C" fn invoke(&self) {
unsafe { asm!("", options(noreturn)) } unsafe { naked_asm!("") }
} }
} }
#[naked] #[naked]
extern "C" fn ok() { extern "C" fn ok() {
unsafe { asm!("", options(noreturn)) } unsafe { naked_asm!("") }
} }
impl S { impl S {
#[naked] #[naked]
extern "C" fn g() { extern "C" fn g() {
unsafe { asm!("", options(noreturn)) } unsafe { naked_asm!("") }
} }
#[naked] #[naked]
extern "C" fn h(&self) { extern "C" fn h(&self) {
unsafe { asm!("", options(noreturn)) } unsafe { naked_asm!("") }
} }
} }
fn main() { fn main() {
#[naked] || {}; //~ ERROR should be applied to a function definition #[naked] //~ ERROR should be applied to a function definition
|| {};
} }

View File

@ -13,8 +13,10 @@ LL | | }
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/naked-invalid-attr.rs:51:5 --> $DIR/naked-invalid-attr.rs:51:5
| |
LL | #[naked] || {}; LL | #[naked]
| ^^^^^^^^ ----- not a function definition | ^^^^^^^^
LL | || {};
| ----- not a function definition
error: attribute should be applied to a function definition error: attribute should be applied to a function definition
--> $DIR/naked-invalid-attr.rs:22:5 --> $DIR/naked-invalid-attr.rs:22:5

View File

@ -2,14 +2,14 @@
#![feature(naked_functions)] #![feature(naked_functions)]
#![feature(fn_align)] #![feature(fn_align)]
#![crate_type = "lib"] #![crate_type = "lib"]
use std::arch::asm; use std::arch::naked_asm;
#[repr(C)] #[repr(C)]
//~^ ERROR attribute should be applied to a struct, enum, or union [E0517] //~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
#[naked] #[naked]
extern "C" fn example1() { extern "C" fn example1() {
//~^ NOTE not a struct, enum, or union //~^ NOTE not a struct, enum, or union
unsafe { asm!("", options(noreturn)) } unsafe { naked_asm!("") }
} }
#[repr(transparent)] #[repr(transparent)]
@ -17,7 +17,7 @@ extern "C" fn example1() {
#[naked] #[naked]
extern "C" fn example2() { extern "C" fn example2() {
//~^ NOTE not a struct, enum, or union //~^ NOTE not a struct, enum, or union
unsafe { asm!("", options(noreturn)) } unsafe { naked_asm!("") }
} }
#[repr(align(16), C)] #[repr(align(16), C)]
@ -25,7 +25,7 @@ extern "C" fn example2() {
#[naked] #[naked]
extern "C" fn example3() { extern "C" fn example3() {
//~^ NOTE not a struct, enum, or union //~^ NOTE not a struct, enum, or union
unsafe { asm!("", options(noreturn)) } unsafe { naked_asm!("") }
} }
// note: two errors because of packed and C // note: two errors because of packed and C
@ -36,7 +36,7 @@ extern "C" fn example3() {
extern "C" fn example4() { extern "C" fn example4() {
//~^ NOTE not a struct, enum, or union //~^ NOTE not a struct, enum, or union
//~| NOTE not a struct or union //~| NOTE not a struct or union
unsafe { asm!("", options(noreturn)) } unsafe { naked_asm!("") }
} }
#[repr(u8)] #[repr(u8)]
@ -44,5 +44,5 @@ extern "C" fn example4() {
#[naked] #[naked]
extern "C" fn example5() { extern "C" fn example5() {
//~^ NOTE not an enum //~^ NOTE not an enum
unsafe { asm!("", options(noreturn)) } unsafe { naked_asm!("") }
} }

View File

@ -6,7 +6,7 @@ LL | #[repr(C)]
... ...
LL | / extern "C" fn example1() { LL | / extern "C" fn example1() {
LL | | LL | |
LL | | unsafe { asm!("", options(noreturn)) } LL | | unsafe { naked_asm!("") }
LL | | } LL | | }
| |_- not a struct, enum, or union | |_- not a struct, enum, or union
@ -18,7 +18,7 @@ LL | #[repr(transparent)]
... ...
LL | / extern "C" fn example2() { LL | / extern "C" fn example2() {
LL | | LL | |
LL | | unsafe { asm!("", options(noreturn)) } LL | | unsafe { naked_asm!("") }
LL | | } LL | | }
| |_- not a struct, enum, or union | |_- not a struct, enum, or union
@ -30,7 +30,7 @@ LL | #[repr(align(16), C)]
... ...
LL | / extern "C" fn example3() { LL | / extern "C" fn example3() {
LL | | LL | |
LL | | unsafe { asm!("", options(noreturn)) } LL | | unsafe { naked_asm!("") }
LL | | } LL | | }
| |_- not a struct, enum, or union | |_- not a struct, enum, or union
@ -43,7 +43,7 @@ LL | #[repr(C, packed)]
LL | / extern "C" fn example4() { LL | / extern "C" fn example4() {
LL | | LL | |
LL | | LL | |
LL | | unsafe { asm!("", options(noreturn)) } LL | | unsafe { naked_asm!("") }
LL | | } LL | | }
| |_- not a struct, enum, or union | |_- not a struct, enum, or union
@ -56,7 +56,7 @@ LL | #[repr(C, packed)]
LL | / extern "C" fn example4() { LL | / extern "C" fn example4() {
LL | | LL | |
LL | | LL | |
LL | | unsafe { asm!("", options(noreturn)) } LL | | unsafe { naked_asm!("") }
LL | | } LL | | }
| |_- not a struct or union | |_- not a struct or union
@ -68,7 +68,7 @@ LL | #[repr(u8)]
... ...
LL | / extern "C" fn example5() { LL | / extern "C" fn example5() {
LL | | LL | |
LL | | unsafe { asm!("", options(noreturn)) } LL | | unsafe { naked_asm!("") }
LL | | } LL | | }
| |_- not an enum | |_- not an enum

View File

@ -12,7 +12,7 @@
#![feature(naked_functions)] #![feature(naked_functions)]
use std::arch::{asm, global_asm}; use std::arch::{asm, global_asm, naked_asm};
#[no_mangle] #[no_mangle]
pub static FOO: usize = 42; pub static FOO: usize = 42;
@ -177,7 +177,7 @@ fn main() {
// label or LTO can cause labels to break // label or LTO can cause labels to break
#[naked] #[naked]
pub extern "C" fn foo() -> i32 { pub extern "C" fn foo() -> i32 {
unsafe { asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1, options(noreturn)) } unsafe { naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) }
//~^ ERROR avoid using named labels //~^ ERROR avoid using named labels
} }
@ -192,7 +192,7 @@ pub extern "C" fn bar() {
pub extern "C" fn aaa() { pub extern "C" fn aaa() {
fn _local() {} fn _local() {}
unsafe { asm!(".Laaa: nop; ret;", options(noreturn)) } //~ ERROR avoid using named labels unsafe { naked_asm!(".Laaa: nop; ret;") } //~ ERROR avoid using named labels
} }
pub fn normal() { pub fn normal() {
@ -202,7 +202,7 @@ fn _local1() {}
pub extern "C" fn bbb() { pub extern "C" fn bbb() {
fn _very_local() {} fn _very_local() {}
unsafe { asm!(".Lbbb: nop; ret;", options(noreturn)) } //~ ERROR avoid using named labels unsafe { naked_asm!(".Lbbb: nop; ret;") } //~ ERROR avoid using named labels
} }
fn _local2() {} fn _local2() {}
@ -221,7 +221,7 @@ fn closures() {
|| { || {
#[naked] #[naked]
unsafe extern "C" fn _nested() { unsafe extern "C" fn _nested() {
asm!("ret;", options(noreturn)); naked_asm!("ret;");
} }
unsafe { unsafe {

View File

@ -475,10 +475,10 @@ LL | #[warn(named_asm_labels)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: avoid using named labels in inline assembly error: avoid using named labels in inline assembly
--> $DIR/named-asm-labels.rs:180:20 --> $DIR/named-asm-labels.rs:180:26
| |
LL | unsafe { asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1, options(noreturn)) } LL | unsafe { naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) }
| ^^^^^ | ^^^^^
| |
= help: only local labels of the form `<number>:` should be used in inline asm = help: only local labels of the form `<number>:` should be used in inline asm
= note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
@ -493,19 +493,19 @@ LL | unsafe { asm!(".Lbar: mov rax, {}; ret;", "nop", const 1, options(noret
= note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
error: avoid using named labels in inline assembly error: avoid using named labels in inline assembly
--> $DIR/named-asm-labels.rs:195:20 --> $DIR/named-asm-labels.rs:195:26
| |
LL | unsafe { asm!(".Laaa: nop; ret;", options(noreturn)) } LL | unsafe { naked_asm!(".Laaa: nop; ret;") }
| ^^^^^ | ^^^^^
| |
= help: only local labels of the form `<number>:` should be used in inline asm = help: only local labels of the form `<number>:` should be used in inline asm
= note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
error: avoid using named labels in inline assembly error: avoid using named labels in inline assembly
--> $DIR/named-asm-labels.rs:205:24 --> $DIR/named-asm-labels.rs:205:30
| |
LL | unsafe { asm!(".Lbbb: nop; ret;", options(noreturn)) } LL | unsafe { naked_asm!(".Lbbb: nop; ret;") }
| ^^^^^ | ^^^^^
| |
= help: only local labels of the form `<number>:` should be used in inline asm = help: only local labels of the form `<number>:` should be used in inline asm
= note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information

View File

@ -6,7 +6,7 @@
#[naked] #[naked]
//~^ the `#[naked]` attribute is an experimental feature //~^ the `#[naked]` attribute is an experimental feature
extern "C" fn naked() { extern "C" fn naked() {
naked_asm!("", options(noreturn)) naked_asm!("")
//~^ ERROR use of unstable library feature 'naked_functions' //~^ ERROR use of unstable library feature 'naked_functions'
//~| ERROR: requires unsafe //~| ERROR: requires unsafe
} }
@ -14,7 +14,7 @@ extern "C" fn naked() {
#[naked] #[naked]
//~^ the `#[naked]` attribute is an experimental feature //~^ the `#[naked]` attribute is an experimental feature
extern "C" fn naked_2() -> isize { extern "C" fn naked_2() -> isize {
naked_asm!("", options(noreturn)) naked_asm!("")
//~^ ERROR use of unstable library feature 'naked_functions' //~^ ERROR use of unstable library feature 'naked_functions'
//~| ERROR: requires unsafe //~| ERROR: requires unsafe
} }