Rollup merge of #93153 - tmiasko:reject-unsupported-naked-functions, r=Amanieu

Reject unsupported naked functions

Transition unsupported naked functions future incompatibility lint into an error:

* Naked functions must contain a single inline assembly block. Introduced as future incompatibility lint in 1.50 #79653. Change into an error fixes a soundness issue described in #32489.

* Naked functions must not use any forms of inline attribute. Introduced as future incompatibility lint in 1.56 #87652.

Closes #32490.
Closes #32489.

r? ```@Amanieu``` ```@npmccallum``` ```@joshtriplett```
This commit is contained in:
Matthias Krüger 2022-01-22 15:32:54 +01:00 committed by GitHub
commit a8f64c0415
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 195 additions and 295 deletions

View file

@ -486,6 +486,7 @@ E0783: include_str!("./error_codes/E0783.md"),
E0784: include_str!("./error_codes/E0784.md"), E0784: include_str!("./error_codes/E0784.md"),
E0785: include_str!("./error_codes/E0785.md"), E0785: include_str!("./error_codes/E0785.md"),
E0786: include_str!("./error_codes/E0786.md"), E0786: include_str!("./error_codes/E0786.md"),
E0787: include_str!("./error_codes/E0787.md"),
; ;
// E0006, // merged with E0005 // E0006, // merged with E0005
// E0008, // cannot bind by-move into a pattern guard // E0008, // cannot bind by-move into a pattern guard

View file

@ -0,0 +1,28 @@
An unsupported naked function definition.
Erroneous code example:
```compile_fail,E0787
#![feature(naked_functions)]
#[naked]
pub extern "C" fn f() -> u32 {
42
}
```
The naked functions must be defined using a single inline assembly
block.
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
use `att_syntax` and `raw` options, but others options are not allowed.
The asm block must not contain any operands other than `const` and
`sym`.
### Additional information
For more information, please see [RFC 2972].
[RFC 2972]: https://github.com/rust-lang/rfcs/blob/master/text/2972-constrained-naked.md

View file

@ -481,6 +481,11 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
<https://github.com/rust-lang/rust/issues/59014> for more information", <https://github.com/rust-lang/rust/issues/59014> for more information",
); );
store.register_removed("plugin_as_library", "plugins have been deprecated and retired"); store.register_removed("plugin_as_library", "plugins have been deprecated and retired");
store.register_removed(
"unsupported_naked_functions",
"converted into hard error, see RFC 2972 \
<https://github.com/rust-lang/rfcs/blob/master/text/2972-constrained-naked.md> for more information",
);
} }
fn register_internals(store: &mut LintStore) { fn register_internals(store: &mut LintStore) {

View file

@ -2759,52 +2759,6 @@ declare_lint! {
"undefined naked function ABI" "undefined naked function ABI"
} }
declare_lint! {
/// The `unsupported_naked_functions` lint detects naked function
/// definitions that are unsupported but were previously accepted.
///
/// ### Example
///
/// ```rust
/// #![feature(naked_functions)]
///
/// #[naked]
/// pub extern "C" fn f() -> u32 {
/// 42
/// }
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The naked functions must be defined using a single inline assembly
/// block.
///
/// 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
/// use `att_syntax` option, but other options are not allowed.
///
/// The asm block must not contain any operands other than `const` and
/// `sym`. Additionally, naked function should specify a non-Rust ABI.
///
/// Naked functions cannot be inlined. All forms of the `inline` attribute
/// are prohibited.
///
/// While other definitions of naked functions were previously accepted,
/// they are unsupported and might not work reliably. This is a
/// [future-incompatible] lint that will transition into hard error in
/// the future.
///
/// [future-incompatible]: ../index.md#future-incompatible-lints
pub UNSUPPORTED_NAKED_FUNCTIONS,
Warn,
"unsupported naked function definitions",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #32408 <https://github.com/rust-lang/rust/issues/32408>",
};
}
declare_lint! { declare_lint! {
/// The `ineffective_unstable_trait_impl` lint detects `#[unstable]` attributes which are not used. /// The `ineffective_unstable_trait_impl` lint detects `#[unstable]` attributes which are not used.
/// ///
@ -3070,7 +3024,6 @@ declare_lint_pass! {
UNINHABITED_STATIC, UNINHABITED_STATIC,
FUNCTION_ITEM_REFERENCES, FUNCTION_ITEM_REFERENCES,
USELESS_DEPRECATED, USELESS_DEPRECATED,
UNSUPPORTED_NAKED_FUNCTIONS,
MISSING_ABI, MISSING_ABI,
INVALID_DOC_ATTRIBUTES, INVALID_DOC_ATTRIBUTES,
SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,

View file

@ -1,6 +1,7 @@
//! Checks validity of naked functions. //! Checks validity of naked functions.
use rustc_ast::{Attribute, InlineAsmOptions}; use rustc_ast::{Attribute, InlineAsmOptions};
use rustc_errors::struct_span_err;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::{FnKind, Visitor}; use rustc_hir::intravisit::{FnKind, Visitor};
@ -8,7 +9,6 @@ use rustc_hir::{ExprKind, HirId, InlineAsmOperand, StmtKind};
use rustc_middle::ty::query::Providers; use rustc_middle::ty::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_session::lint::builtin::UNSUPPORTED_NAKED_FUNCTIONS;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::Span; use rustc_span::Span;
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
@ -64,18 +64,16 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> {
check_abi(self.tcx, hir_id, fn_header.abi, ident_span); check_abi(self.tcx, hir_id, fn_header.abi, ident_span);
check_no_patterns(self.tcx, body.params); check_no_patterns(self.tcx, body.params);
check_no_parameters_use(self.tcx, body); check_no_parameters_use(self.tcx, body);
check_asm(self.tcx, hir_id, body, span); check_asm(self.tcx, body, span);
check_inline(self.tcx, hir_id, attrs); check_inline(self.tcx, attrs);
} }
} }
} }
/// Check that the function isn't inlined. /// Check that the function isn't inlined.
fn check_inline(tcx: TyCtxt<'_>, hir_id: HirId, attrs: &[Attribute]) { fn check_inline(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
for attr in attrs.iter().filter(|attr| attr.has_name(sym::inline)) { for attr in attrs.iter().filter(|attr| attr.has_name(sym::inline)) {
tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, attr.span, |lint| { tcx.sess.struct_span_err(attr.span, "naked functions cannot be inlined").emit();
lint.build("naked functions cannot be inlined").emit();
});
} }
} }
@ -146,31 +144,31 @@ impl<'tcx> Visitor<'tcx> for CheckParameters<'tcx> {
} }
/// Checks that function body contains a single inline assembly block. /// Checks that function body contains a single inline assembly block.
fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, hir_id: HirId, body: &'tcx hir::Body<'tcx>, fn_span: Span) { fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, body: &'tcx hir::Body<'tcx>, fn_span: Span) {
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, _)] = this.items[..] { if let [(ItemKind::Asm, _)] = this.items[..] {
// Ok. // Ok.
} else { } else {
tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, fn_span, |lint| { let mut diag = struct_span_err!(
let mut diag = lint.build("naked functions must contain a single asm block"); tcx.sess,
let mut has_asm = false; fn_span,
for &(kind, span) in &this.items { E0787,
match kind { "naked functions must contain a single asm block"
ItemKind::Asm if has_asm => { );
diag.span_label( let mut has_asm = false;
span, for &(kind, span) in &this.items {
"multiple asm blocks are unsupported in naked functions", match kind {
); ItemKind::Asm if has_asm => {
} diag.span_label(span, "multiple asm blocks are unsupported in naked functions");
ItemKind::Asm => has_asm = true, }
ItemKind::NonAsm => { ItemKind::Asm => has_asm = true,
diag.span_label(span, "non-asm is unsupported in naked functions"); ItemKind::NonAsm => {
} diag.span_label(span, "non-asm is unsupported in naked functions");
} }
} }
diag.emit(); }
}); diag.emit();
} }
} }
@ -221,7 +219,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
ExprKind::InlineAsm(ref asm) => { ExprKind::InlineAsm(ref asm) => {
self.items.push((ItemKind::Asm, span)); self.items.push((ItemKind::Asm, span));
self.check_inline_asm(expr.hir_id, asm, span); self.check_inline_asm(asm, span);
} }
ExprKind::DropTemps(..) | ExprKind::Block(..) | ExprKind::Err => { ExprKind::DropTemps(..) | ExprKind::Block(..) | ExprKind::Err => {
@ -230,7 +228,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
} }
} }
fn check_inline_asm(&self, hir_id: HirId, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) { fn check_inline_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) {
let unsupported_operands: Vec<Span> = asm let unsupported_operands: Vec<Span> = asm
.operands .operands
.iter() .iter()
@ -243,18 +241,17 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
}) })
.collect(); .collect();
if !unsupported_operands.is_empty() { if !unsupported_operands.is_empty() {
self.tcx.struct_span_lint_hir( struct_span_err!(
UNSUPPORTED_NAKED_FUNCTIONS, self.tcx.sess,
hir_id,
unsupported_operands, unsupported_operands,
|lint| { E0787,
lint.build("only `const` and `sym` operands are supported in naked functions") "only `const` and `sym` operands are supported in naked functions",
.emit(); )
}, .emit();
);
} }
let unsupported_options: Vec<&'static str> = [ let unsupported_options: Vec<&'static str> = [
(InlineAsmOptions::MAY_UNWIND, "`may_unwind`"),
(InlineAsmOptions::NOMEM, "`nomem`"), (InlineAsmOptions::NOMEM, "`nomem`"),
(InlineAsmOptions::NOSTACK, "`nostack`"), (InlineAsmOptions::NOSTACK, "`nostack`"),
(InlineAsmOptions::PRESERVES_FLAGS, "`preserves_flags`"), (InlineAsmOptions::PRESERVES_FLAGS, "`preserves_flags`"),
@ -266,19 +263,24 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
.collect(); .collect();
if !unsupported_options.is_empty() { if !unsupported_options.is_empty() {
self.tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, span, |lint| { struct_span_err!(
lint.build(&format!( self.tcx.sess,
"asm options unsupported in naked functions: {}", span,
unsupported_options.join(", ") E0787,
)) "asm options unsupported in naked functions: {}",
.emit(); unsupported_options.join(", ")
}); )
.emit();
} }
if !asm.options.contains(InlineAsmOptions::NORETURN) { if !asm.options.contains(InlineAsmOptions::NORETURN) {
self.tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, span, |lint| { struct_span_err!(
lint.build("asm in naked functions must use `noreturn` option").emit(); self.tcx.sess,
}); span,
E0787,
"asm in naked functions must use `noreturn` option"
)
.emit();
} }
} }
} }

View file

@ -1,42 +1,32 @@
// compile-flags: -C no-prepopulate-passes // compile-flags: -C no-prepopulate-passes
// needs-asm-support
// only-x86_64
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(naked_functions)] #![feature(naked_functions)]
use std::arch::asm;
// CHECK: Function Attrs: naked // CHECK: Function Attrs: naked
// CHECK-NEXT: define{{.*}}void @naked_empty() // CHECK-NEXT: define{{.*}}void @naked_empty()
#[no_mangle] #[no_mangle]
#[naked] #[naked]
pub fn naked_empty() { pub unsafe extern "C" fn naked_empty() {
// CHECK-NEXT: {{.+}}: // CHECK-NEXT: {{.+}}:
// CHECK-NEXT: ret void // CHECK-NEXT: call void asm
// CHECK-NEXT: unreachable
asm!("ret",
options(noreturn));
} }
// CHECK: Function Attrs: naked // CHECK: Function Attrs: naked
// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i64 %a, i64 %b)
#[no_mangle] #[no_mangle]
#[naked] #[naked]
// CHECK-NEXT: define{{.*}}void @naked_with_args(i{{[0-9]+( %a)?}}) pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
pub fn naked_with_args(a: isize) {
// CHECK-NEXT: {{.+}}: // CHECK-NEXT: {{.+}}:
// CHECK: ret void // CHECK-NEXT: call void asm
} // CHECK-NEXT: unreachable
asm!("lea rax, [rdi + rsi]",
// CHECK: Function Attrs: naked "ret",
// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_return() options(noreturn));
#[no_mangle]
#[naked]
pub fn naked_with_return() -> isize {
// CHECK-NEXT: {{.+}}:
// CHECK-NEXT: ret i{{[0-9]+}} 0
0
}
// CHECK: Function Attrs: naked
// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i{{[0-9]+( %a)?}})
#[no_mangle]
#[naked]
pub fn naked_with_args_and_return(a: isize) -> isize {
// CHECK-NEXT: {{.+}}:
// CHECK: ret i{{[0-9]+}} 0
0
} }

View file

@ -7,7 +7,6 @@
use std::arch::asm; use std::arch::asm;
#[inline(always)]
#[naked] #[naked]
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn f() { pub unsafe extern "C" fn f() {

View file

@ -5,7 +5,7 @@
#![feature(naked_functions)] #![feature(naked_functions)]
#![feature(or_patterns)] #![feature(or_patterns)]
#![feature(asm_const, asm_sym)] #![feature(asm_const, asm_sym, asm_unwind)]
#![crate_type = "lib"] #![crate_type = "lib"]
use std::arch::asm; use std::arch::asm;
@ -32,8 +32,7 @@ pub unsafe extern "C" fn patterns(
#[naked] #[naked]
pub unsafe extern "C" fn inc(a: u32) -> u32 { pub unsafe extern "C" fn inc(a: u32) -> u32 {
//~^ WARN naked functions must contain a single asm block //~^ ERROR naked functions must contain a single asm block
//~| WARN this was previously accepted
a + 1 a + 1
//~^ ERROR referencing function parameters is not allowed in naked functions //~^ ERROR referencing function parameters is not allowed in naked functions
} }
@ -42,21 +41,18 @@ pub unsafe extern "C" fn inc(a: u32) -> u32 {
pub unsafe extern "C" fn inc_asm(a: u32) -> u32 { pub unsafe extern "C" fn inc_asm(a: u32) -> u32 {
asm!("/* {0} */", in(reg) a, options(noreturn)); asm!("/* {0} */", in(reg) a, options(noreturn));
//~^ ERROR referencing function parameters is not allowed in naked functions //~^ ERROR referencing function parameters is not allowed in naked functions
//~| WARN only `const` and `sym` operands are supported in naked functions //~| ERROR only `const` and `sym` operands are supported in naked functions
//~| WARN this was previously accepted
} }
#[naked] #[naked]
pub unsafe extern "C" fn inc_closure(a: u32) -> u32 { pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
//~^ WARN naked functions must contain a single asm block //~^ ERROR naked functions must contain a single asm block
//~| WARN this was previously accepted
(|| a + 1)() (|| a + 1)()
} }
#[naked] #[naked]
pub unsafe extern "C" fn unsupported_operands() { pub unsafe extern "C" fn unsupported_operands() {
//~^ WARN naked functions must contain a single asm block //~^ ERROR naked functions must contain a single asm block
//~| WARN this was previously accepted
let mut a = 0usize; let mut a = 0usize;
let mut b = 0usize; let mut b = 0usize;
let mut c = 0usize; let mut c = 0usize;
@ -65,11 +61,9 @@ pub unsafe extern "C" fn unsupported_operands() {
const F: usize = 0usize; const F: usize = 0usize;
static G: usize = 0usize; static G: usize = 0usize;
asm!("/* {0} {1} {2} {3} {4} {5} {6} */", asm!("/* {0} {1} {2} {3} {4} {5} {6} */",
//~^ WARN asm in naked functions must use `noreturn` option //~^ ERROR asm in naked functions must use `noreturn` option
//~| WARN this was previously accepted
in(reg) a, in(reg) a,
//~^ WARN only `const` and `sym` operands are supported in naked functions //~^ ERROR only `const` and `sym` operands are supported in naked functions
//~| WARN this was previously accepted
inlateout(reg) b, inlateout(reg) b,
inout(reg) c, inout(reg) c,
lateout(reg) d, lateout(reg) d,
@ -81,31 +75,25 @@ pub unsafe extern "C" fn unsupported_operands() {
#[naked] #[naked]
pub extern "C" fn missing_assembly() { pub extern "C" fn missing_assembly() {
//~^ WARN naked functions must contain a single asm block //~^ ERROR naked functions must contain a single asm block
//~| WARN this was previously accepted
} }
#[naked] #[naked]
pub extern "C" fn too_many_asm_blocks() { pub extern "C" fn too_many_asm_blocks() {
//~^ WARN naked functions must contain a single asm block //~^ ERROR naked functions must contain a single asm block
//~| WARN this was previously accepted
asm!(""); asm!("");
//~^ WARN asm in naked functions must use `noreturn` option //~^ ERROR asm in naked functions must use `noreturn` option
//~| WARN this was previously accepted
asm!(""); asm!("");
//~^ WARN asm in naked functions must use `noreturn` option //~^ ERROR asm in naked functions must use `noreturn` option
//~| WARN this was previously accepted
asm!(""); asm!("");
//~^ WARN asm in naked functions must use `noreturn` option //~^ ERROR asm in naked functions must use `noreturn` option
//~| WARN this was previously accepted
asm!("", options(noreturn)); asm!("", options(noreturn));
} }
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 {
//~^ WARN naked functions must contain a single asm block //~^ ERROR naked functions must contain a single asm block
//~| WARN this was previously accepted
*&y *&y
//~^ ERROR referencing function parameters is not allowed in naked functions //~^ ERROR referencing function parameters is not allowed in naked functions
} }
@ -115,18 +103,21 @@ pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
#[naked] #[naked]
unsafe extern "C" fn invalid_options() { unsafe extern "C" fn invalid_options() {
asm!("", options(nomem, preserves_flags, noreturn)); asm!("", options(nomem, preserves_flags, noreturn));
//~^ WARN asm options unsupported in naked functions: `nomem`, `preserves_flags` //~^ ERROR asm options unsupported in naked functions: `nomem`, `preserves_flags`
//~| WARN this was previously accepted
} }
#[naked] #[naked]
unsafe extern "C" fn invalid_options_continued() { unsafe extern "C" fn invalid_options_continued() {
asm!("", options(readonly, nostack), options(pure)); asm!("", options(readonly, nostack), options(pure));
//~^ ERROR asm with the `pure` option must have at least one output //~^ ERROR asm with the `pure` option must have at least one output
//~| WARN asm options unsupported in naked functions: `nostack`, `pure`, `readonly` //~| ERROR asm options unsupported in naked functions: `nostack`, `pure`, `readonly`
//~| WARN this was previously accepted //~| ERROR asm in naked functions must use `noreturn` option
//~| WARN asm in naked functions must use `noreturn` option }
//~| WARN this was previously accepted
#[naked]
unsafe extern "C" fn invalid_may_unwind() {
asm!("", options(noreturn, may_unwind));
//~^ ERROR asm options unsupported in naked functions: `may_unwind`
} }
#[naked] #[naked]
@ -177,38 +168,32 @@ pub unsafe extern "C" fn inline_none() {
#[naked] #[naked]
#[inline] #[inline]
//~^ WARN naked functions cannot be inlined //~^ ERROR naked functions cannot be inlined
//~| WARN this was previously accepted
pub unsafe extern "C" fn inline_hint() { pub unsafe extern "C" fn inline_hint() {
asm!("", options(noreturn)); asm!("", options(noreturn));
} }
#[naked] #[naked]
#[inline(always)] #[inline(always)]
//~^ WARN naked functions cannot be inlined //~^ ERROR naked functions cannot be inlined
//~| WARN this was previously accepted
pub unsafe extern "C" fn inline_always() { pub unsafe extern "C" fn inline_always() {
asm!("", options(noreturn)); asm!("", options(noreturn));
} }
#[naked] #[naked]
#[inline(never)] #[inline(never)]
//~^ WARN naked functions cannot be inlined //~^ ERROR naked functions cannot be inlined
//~| WARN this was previously accepted
pub unsafe extern "C" fn inline_never() { pub unsafe extern "C" fn inline_never() {
asm!("", options(noreturn)); asm!("", options(noreturn));
} }
#[naked] #[naked]
#[inline] #[inline]
//~^ WARN naked functions cannot be inlined //~^ ERROR naked functions cannot be inlined
//~| WARN this was previously accepted
#[inline(always)] #[inline(always)]
//~^ WARN naked functions cannot be inlined //~^ ERROR naked functions cannot be inlined
//~| WARN this was previously accepted
#[inline(never)] #[inline(never)]
//~^ WARN naked functions cannot be inlined //~^ ERROR naked functions cannot be inlined
//~| WARN this was previously accepted
pub unsafe extern "C" fn inline_all() { pub unsafe extern "C" fn inline_all() {
asm!("", options(noreturn)); asm!("", options(noreturn));
} }

View file

@ -1,5 +1,5 @@
error: asm with the `pure` option must have at least one output error: asm with the `pure` option must have at least one output
--> $DIR/naked-functions.rs:124:14 --> $DIR/naked-functions.rs:111:14
| |
LL | asm!("", options(readonly, nostack), options(pure)); LL | asm!("", options(readonly, nostack), options(pure));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
@ -29,66 +29,54 @@ 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:37:5 --> $DIR/naked-functions.rs:36: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
warning: naked functions must contain a single asm block error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:34:1 --> $DIR/naked-functions.rs:34:1
| |
LL | / pub unsafe extern "C" fn inc(a: u32) -> u32 { LL | / pub unsafe extern "C" fn inc(a: u32) -> u32 {
LL | | LL | |
LL | |
LL | | a + 1 LL | | a + 1
| | ----- non-asm is unsupported in naked functions | | ----- non-asm is unsupported in naked functions
LL | | LL | |
LL | | } LL | | }
| |_^ | |_^
|
= note: `#[warn(unsupported_naked_functions)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
error: referencing function parameters is not allowed in naked functions error: referencing function parameters is not allowed in naked functions
--> $DIR/naked-functions.rs:43:31 --> $DIR/naked-functions.rs:42:31
| |
LL | asm!("/* {0} */", in(reg) a, options(noreturn)); LL | asm!("/* {0} */", in(reg) a, options(noreturn));
| ^ | ^
| |
= help: follow the calling convention in asm block to use parameters = help: follow the calling convention in asm block to use parameters
warning: only `const` and `sym` operands are supported in naked functions error[E0787]: only `const` and `sym` operands are supported in naked functions
--> $DIR/naked-functions.rs:43:23 --> $DIR/naked-functions.rs:42:23
| |
LL | asm!("/* {0} */", in(reg) a, options(noreturn)); LL | asm!("/* {0} */", in(reg) a, options(noreturn));
| ^^^^^^^^^ | ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions must contain a single asm block error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:50:1 --> $DIR/naked-functions.rs:48: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 | |
LL | | (|| a + 1)() LL | | (|| a + 1)()
| | ------------ non-asm is unsupported in naked functions | | ------------ non-asm is unsupported in naked functions
LL | | } LL | | }
| |_^ | |_^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: only `const` and `sym` operands are supported in naked functions error[E0787]: only `const` and `sym` operands are supported in naked functions
--> $DIR/naked-functions.rs:70:10 --> $DIR/naked-functions.rs:65:10
| |
LL | in(reg) a, LL | in(reg) a,
| ^^^^^^^^^ | ^^^^^^^^^
... LL |
LL | inlateout(reg) b, LL | inlateout(reg) b,
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
LL | inout(reg) c, LL | inout(reg) c,
@ -97,31 +85,24 @@ LL | lateout(reg) d,
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
LL | out(reg) e, LL | out(reg) e,
| ^^^^^^^^^^ | ^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: asm in naked functions must use `noreturn` option error[E0787]: asm in naked functions must use `noreturn` option
--> $DIR/naked-functions.rs:67:5 --> $DIR/naked-functions.rs:63:5
| |
LL | / asm!("/* {0} {1} {2} {3} {4} {5} {6} */", LL | / asm!("/* {0} {1} {2} {3} {4} {5} {6} */",
LL | | LL | |
LL | |
LL | | in(reg) a, LL | | in(reg) a,
LL | |
... | ... |
LL | | sym G, LL | | sym G,
LL | | ); LL | | );
| |_____^ | |_____^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions must contain a single asm block error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:57:1 --> $DIR/naked-functions.rs:54:1
| |
LL | / pub unsafe extern "C" fn unsupported_operands() { LL | / pub unsafe extern "C" fn unsupported_operands() {
LL | | LL | |
LL | |
LL | | let mut a = 0usize; LL | | let mut a = 0usize;
| | ------------------- non-asm is unsupported in naked functions | | ------------------- non-asm is unsupported in naked functions
LL | | let mut b = 0usize; LL | | let mut b = 0usize;
@ -136,123 +117,96 @@ LL | | let mut e = 0usize;
LL | | ); LL | | );
LL | | } LL | | }
| |_^ | |_^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions must contain a single asm block error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:83:1 --> $DIR/naked-functions.rs:77:1
| |
LL | / pub extern "C" fn missing_assembly() { LL | / pub extern "C" fn missing_assembly() {
LL | | LL | |
LL | |
LL | | } LL | | }
| |_^ | |_^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: asm in naked functions must use `noreturn` option error[E0787]: asm in naked functions must use `noreturn` option
--> $DIR/naked-functions.rs:92:5 --> $DIR/naked-functions.rs:84:5
| |
LL | asm!(""); LL | asm!("");
| ^^^^^^^^ | ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: asm in naked functions must use `noreturn` option error[E0787]: asm in naked functions must use `noreturn` option
--> $DIR/naked-functions.rs:95:5 --> $DIR/naked-functions.rs:86:5
| |
LL | asm!(""); LL | asm!("");
| ^^^^^^^^ | ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: asm in naked functions must use `noreturn` option error[E0787]: asm in naked functions must use `noreturn` option
--> $DIR/naked-functions.rs:98:5 --> $DIR/naked-functions.rs:88:5
| |
LL | asm!(""); LL | asm!("");
| ^^^^^^^^ | ^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions must contain a single asm block error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:89:1 --> $DIR/naked-functions.rs:82:1
| |
LL | / pub extern "C" fn too_many_asm_blocks() { LL | / pub extern "C" fn too_many_asm_blocks() {
LL | | LL | |
LL | | asm!("");
LL | | LL | |
LL | | asm!(""); LL | | asm!("");
... | | | -------- multiple asm blocks are unsupported in naked functions
LL | |
LL | | asm!(""); LL | | asm!("");
| | -------- multiple asm blocks are unsupported in naked functions | | -------- multiple asm blocks are unsupported in naked functions
... | LL | |
LL | | asm!("");
| | -------- multiple asm blocks are unsupported in naked functions
... |
LL | | asm!("", options(noreturn)); LL | | asm!("", options(noreturn));
| | --------------------------- multiple asm blocks are unsupported in naked functions | | --------------------------- multiple asm blocks are unsupported in naked functions
LL | | } LL | | }
| |_^ | |_^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
error: referencing function parameters is not allowed in naked functions error: referencing function parameters is not allowed in naked functions
--> $DIR/naked-functions.rs:109:11 --> $DIR/naked-functions.rs:97: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
warning: naked functions must contain a single asm block error[E0787]: naked functions must contain a single asm block
--> $DIR/naked-functions.rs:106:5 --> $DIR/naked-functions.rs:95:5
| |
LL | / pub extern "C" fn inner(y: usize) -> usize { LL | / pub extern "C" fn inner(y: usize) -> usize {
LL | | LL | |
LL | |
LL | | *&y LL | | *&y
| | --- non-asm is unsupported in naked functions | | --- non-asm is unsupported in naked functions
LL | | LL | |
LL | | } LL | | }
| |_____^ | |_____^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: asm options unsupported in naked functions: `nomem`, `preserves_flags` error[E0787]: asm options unsupported in naked functions: `nomem`, `preserves_flags`
--> $DIR/naked-functions.rs:117:5 --> $DIR/naked-functions.rs:105:5
| |
LL | asm!("", options(nomem, preserves_flags, noreturn)); LL | asm!("", options(nomem, preserves_flags, noreturn));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: asm options unsupported in naked functions: `nostack`, `pure`, `readonly` error[E0787]: asm options unsupported in naked functions: `nostack`, `pure`, `readonly`
--> $DIR/naked-functions.rs:124:5 --> $DIR/naked-functions.rs:111:5
| |
LL | asm!("", options(readonly, nostack), options(pure)); LL | asm!("", options(readonly, nostack), options(pure));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: asm in naked functions must use `noreturn` option error[E0787]: asm in naked functions must use `noreturn` option
--> $DIR/naked-functions.rs:124:5 --> $DIR/naked-functions.rs:111:5
| |
LL | asm!("", options(readonly, nostack), options(pure)); LL | asm!("", options(readonly, nostack), options(pure));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0787]: asm options unsupported in naked functions: `may_unwind`
--> $DIR/naked-functions.rs:119:5
| |
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! LL | asm!("", options(noreturn, may_unwind));
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: Rust ABI is unsupported in naked functions warning: Rust ABI is unsupported in naked functions
--> $DIR/naked-functions.rs:133:15 --> $DIR/naked-functions.rs:124:15
| |
LL | pub unsafe fn default_abi() { LL | pub unsafe fn default_abi() {
| ^^^^^^^^^^^ | ^^^^^^^^^^^
@ -260,64 +214,47 @@ 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:139:15 --> $DIR/naked-functions.rs:130:15
| |
LL | pub unsafe fn rust_abi() { LL | pub unsafe fn rust_abi() {
| ^^^^^^^^ | ^^^^^^^^
warning: naked functions cannot be inlined error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:179:1 --> $DIR/naked-functions.rs:170:1
| |
LL | #[inline] LL | #[inline]
| ^^^^^^^^^ | ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:187:1 --> $DIR/naked-functions.rs:177:1
| |
LL | #[inline(always)] LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:184:1
|
LL | #[inline(never)]
| ^^^^^^^^^^^^^^^^
error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:191:1
|
LL | #[inline]
| ^^^^^^^^^
error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:193:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
error: naked functions cannot be inlined
--> $DIR/naked-functions.rs:195:1 --> $DIR/naked-functions.rs:195:1
| |
LL | #[inline(never)] LL | #[inline(never)]
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined error: aborting due to 30 previous errors; 2 warnings emitted
--> $DIR/naked-functions.rs:203:1
|
LL | #[inline]
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:206:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
warning: naked functions cannot be inlined
--> $DIR/naked-functions.rs:209:1
|
LL | #[inline(never)]
| ^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #32408 <https://github.com/rust-lang/rust/issues/32408>
error: aborting due to 8 previous errors; 23 warnings emitted
For more information about this error, try `rustc --explain E0787`.