disallow asm!
in #[naked]
functions
also disallow the `noreturn` option, and infer `naked_asm!` as `!`
This commit is contained in:
parent
1a9c1cbf36
commit
562ec5a6fb
@ -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");`.
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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)]
|
||||||
|
@ -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 });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 */
|
|
||||||
}
|
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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!("");
|
||||||
}
|
}
|
||||||
|
@ -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]
|
||||||
|
@ -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!("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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!("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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!("") };
|
||||||
}
|
}
|
||||||
|
@ -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!("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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`.
|
||||||
|
@ -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
|
||||||
|
|| {};
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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!("") }
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user