From 888332fee42bfccd2a1d1c3d249431c0b741d8ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 21 Jan 2022 00:00:00 +0000 Subject: [PATCH 1/2] 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. --- compiler/rustc_error_codes/src/error_codes.rs | 1 + .../src/error_codes/E0787.md | 28 +++ compiler/rustc_lint/src/lib.rs | 5 + compiler/rustc_lint_defs/src/builtin.rs | 47 ----- compiler/rustc_passes/src/naked_functions.rs | 91 ++++----- src/test/codegen/naked-functions.rs | 40 ++-- src/test/codegen/naked-noinline.rs | 1 - src/test/ui/asm/naked-functions.rs | 63 +++---- src/test/ui/asm/naked-functions.stderr | 177 ++++++------------ 9 files changed, 170 insertions(+), 283 deletions(-) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0787.md diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 79d9c55b5470b..d4b12d00f1ff6 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -486,6 +486,7 @@ E0783: include_str!("./error_codes/E0783.md"), E0784: include_str!("./error_codes/E0784.md"), E0785: include_str!("./error_codes/E0785.md"), E0786: include_str!("./error_codes/E0786.md"), +E0787: include_str!("./error_codes/E0787.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/compiler/rustc_error_codes/src/error_codes/E0787.md b/compiler/rustc_error_codes/src/error_codes/E0787.md new file mode 100644 index 0000000000000..cee5082927026 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0787.md @@ -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 diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 4aa8505c9408d..dde47c1e4c43b 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -481,6 +481,11 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { for more information", ); 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 \ + for more information", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index c2f6118227a4a..4096815c6a426 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -2759,52 +2759,6 @@ declare_lint! { "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 ", - }; -} - declare_lint! { /// The `ineffective_unstable_trait_impl` lint detects `#[unstable]` attributes which are not used. /// @@ -3070,7 +3024,6 @@ declare_lint_pass! { UNINHABITED_STATIC, FUNCTION_ITEM_REFERENCES, USELESS_DEPRECATED, - UNSUPPORTED_NAKED_FUNCTIONS, MISSING_ABI, INVALID_DOC_ATTRIBUTES, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 0228196d1a1a1..e4feb8f136c6f 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -1,6 +1,7 @@ //! Checks validity of naked functions. use rustc_ast::{Attribute, InlineAsmOptions}; +use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; 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::TyCtxt; 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::Span; 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_no_patterns(self.tcx, body.params); check_no_parameters_use(self.tcx, body); - check_asm(self.tcx, hir_id, body, span); - check_inline(self.tcx, hir_id, attrs); + check_asm(self.tcx, body, span); + check_inline(self.tcx, attrs); } } } /// 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)) { - tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, attr.span, |lint| { - lint.build("naked functions cannot be inlined").emit(); - }); + tcx.sess.struct_span_err(attr.span, "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. -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() }; this.visit_body(body); if let [(ItemKind::Asm, _)] = this.items[..] { // Ok. } else { - tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, fn_span, |lint| { - let mut diag = lint.build("naked functions must contain a single asm block"); - let mut has_asm = false; - for &(kind, span) in &this.items { - 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 => { - diag.span_label(span, "non-asm is unsupported in naked functions"); - } + let mut diag = struct_span_err!( + tcx.sess, + fn_span, + E0787, + "naked functions must contain a single asm block" + ); + let mut has_asm = false; + for &(kind, span) in &this.items { + 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 => { + 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) => { 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 => { @@ -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 = asm .operands .iter() @@ -243,15 +241,13 @@ impl<'tcx> CheckInlineAssembly<'tcx> { }) .collect(); if !unsupported_operands.is_empty() { - self.tcx.struct_span_lint_hir( - UNSUPPORTED_NAKED_FUNCTIONS, - hir_id, + struct_span_err!( + self.tcx.sess, unsupported_operands, - |lint| { - lint.build("only `const` and `sym` operands are supported in naked functions") - .emit(); - }, - ); + E0787, + "only `const` and `sym` operands are supported in naked functions", + ) + .emit(); } let unsupported_options: Vec<&'static str> = [ @@ -266,19 +262,24 @@ impl<'tcx> CheckInlineAssembly<'tcx> { .collect(); if !unsupported_options.is_empty() { - self.tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, span, |lint| { - lint.build(&format!( - "asm options unsupported in naked functions: {}", - unsupported_options.join(", ") - )) - .emit(); - }); + struct_span_err!( + self.tcx.sess, + span, + E0787, + "asm options unsupported in naked functions: {}", + unsupported_options.join(", ") + ) + .emit(); } if !asm.options.contains(InlineAsmOptions::NORETURN) { - self.tcx.struct_span_lint_hir(UNSUPPORTED_NAKED_FUNCTIONS, hir_id, span, |lint| { - lint.build("asm in naked functions must use `noreturn` option").emit(); - }); + struct_span_err!( + self.tcx.sess, + span, + E0787, + "asm in naked functions must use `noreturn` option" + ) + .emit(); } } } diff --git a/src/test/codegen/naked-functions.rs b/src/test/codegen/naked-functions.rs index c8cd69232821e..51c7a0c615d00 100644 --- a/src/test/codegen/naked-functions.rs +++ b/src/test/codegen/naked-functions.rs @@ -1,42 +1,32 @@ // compile-flags: -C no-prepopulate-passes +// needs-asm-support +// only-x86_64 #![crate_type = "lib"] #![feature(naked_functions)] +use std::arch::asm; // CHECK: Function Attrs: naked // CHECK-NEXT: define{{.*}}void @naked_empty() #[no_mangle] #[naked] -pub fn naked_empty() { +pub unsafe extern "C" fn naked_empty() { // CHECK-NEXT: {{.+}}: - // CHECK-NEXT: ret void + // CHECK-NEXT: call void asm + // CHECK-NEXT: unreachable + asm!("ret", + options(noreturn)); } // CHECK: Function Attrs: naked +// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i64 %a, i64 %b) #[no_mangle] #[naked] -// CHECK-NEXT: define{{.*}}void @naked_with_args(i{{[0-9]+( %a)?}}) -pub fn naked_with_args(a: isize) { +pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize { // CHECK-NEXT: {{.+}}: - // CHECK: ret void -} - -// CHECK: Function Attrs: naked -// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_return() -#[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 + // CHECK-NEXT: call void asm + // CHECK-NEXT: unreachable + asm!("lea rax, [rdi + rsi]", + "ret", + options(noreturn)); } diff --git a/src/test/codegen/naked-noinline.rs b/src/test/codegen/naked-noinline.rs index e34ccf5c5fe99..13bc139ecd05a 100644 --- a/src/test/codegen/naked-noinline.rs +++ b/src/test/codegen/naked-noinline.rs @@ -7,7 +7,6 @@ use std::arch::asm; -#[inline(always)] #[naked] #[no_mangle] pub unsafe extern "C" fn f() { diff --git a/src/test/ui/asm/naked-functions.rs b/src/test/ui/asm/naked-functions.rs index 32431d9e7c6fe..26397a65cf99a 100644 --- a/src/test/ui/asm/naked-functions.rs +++ b/src/test/ui/asm/naked-functions.rs @@ -32,8 +32,7 @@ pub unsafe extern "C" fn patterns( #[naked] pub unsafe extern "C" fn inc(a: u32) -> u32 { - //~^ WARN naked functions must contain a single asm block - //~| WARN this was previously accepted + //~^ ERROR naked functions must contain a single asm block a + 1 //~^ 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 { asm!("/* {0} */", in(reg) a, options(noreturn)); //~^ ERROR referencing function parameters is not allowed in naked functions - //~| WARN only `const` and `sym` operands are supported in naked functions - //~| WARN this was previously accepted + //~| ERROR only `const` and `sym` operands are supported in naked functions } #[naked] pub unsafe extern "C" fn inc_closure(a: u32) -> u32 { - //~^ WARN naked functions must contain a single asm block - //~| WARN this was previously accepted + //~^ ERROR naked functions must contain a single asm block (|| a + 1)() } #[naked] pub unsafe extern "C" fn unsupported_operands() { - //~^ WARN naked functions must contain a single asm block - //~| WARN this was previously accepted + //~^ ERROR naked functions must contain a single asm block let mut a = 0usize; let mut b = 0usize; let mut c = 0usize; @@ -65,11 +61,9 @@ pub unsafe extern "C" fn unsupported_operands() { const F: usize = 0usize; static G: usize = 0usize; asm!("/* {0} {1} {2} {3} {4} {5} {6} */", - //~^ WARN asm in naked functions must use `noreturn` option - //~| WARN this was previously accepted + //~^ ERROR asm in naked functions must use `noreturn` option in(reg) a, - //~^ WARN only `const` and `sym` operands are supported in naked functions - //~| WARN this was previously accepted + //~^ ERROR only `const` and `sym` operands are supported in naked functions inlateout(reg) b, inout(reg) c, lateout(reg) d, @@ -81,31 +75,25 @@ pub unsafe extern "C" fn unsupported_operands() { #[naked] pub extern "C" fn missing_assembly() { - //~^ WARN naked functions must contain a single asm block - //~| WARN this was previously accepted + //~^ ERROR naked functions must contain a single asm block } #[naked] pub extern "C" fn too_many_asm_blocks() { - //~^ WARN naked functions must contain a single asm block - //~| WARN this was previously accepted + //~^ ERROR naked functions must contain a single asm block asm!(""); - //~^ WARN asm in naked functions must use `noreturn` option - //~| WARN this was previously accepted + //~^ ERROR asm in naked functions must use `noreturn` option asm!(""); - //~^ WARN asm in naked functions must use `noreturn` option - //~| WARN this was previously accepted + //~^ ERROR asm in naked functions must use `noreturn` option asm!(""); - //~^ WARN asm in naked functions must use `noreturn` option - //~| WARN this was previously accepted + //~^ ERROR asm in naked functions must use `noreturn` option asm!("", options(noreturn)); } pub fn outer(x: u32) -> extern "C" fn(usize) -> usize { #[naked] pub extern "C" fn inner(y: usize) -> usize { - //~^ WARN naked functions must contain a single asm block - //~| WARN this was previously accepted + //~^ ERROR naked functions must contain a single asm block *&y //~^ ERROR referencing function parameters is not allowed in naked functions } @@ -115,18 +103,15 @@ pub fn outer(x: u32) -> extern "C" fn(usize) -> usize { #[naked] unsafe extern "C" fn invalid_options() { asm!("", options(nomem, preserves_flags, noreturn)); - //~^ WARN asm options unsupported in naked functions: `nomem`, `preserves_flags` - //~| WARN this was previously accepted + //~^ ERROR asm options unsupported in naked functions: `nomem`, `preserves_flags` } #[naked] unsafe extern "C" fn invalid_options_continued() { asm!("", options(readonly, nostack), options(pure)); //~^ ERROR asm with the `pure` option must have at least one output - //~| WARN asm options unsupported in naked functions: `nostack`, `pure`, `readonly` - //~| WARN this was previously accepted - //~| WARN asm in naked functions must use `noreturn` option - //~| WARN this was previously accepted + //~| ERROR asm options unsupported in naked functions: `nostack`, `pure`, `readonly` + //~| ERROR asm in naked functions must use `noreturn` option } #[naked] @@ -177,38 +162,32 @@ pub unsafe extern "C" fn inline_none() { #[naked] #[inline] -//~^ WARN naked functions cannot be inlined -//~| WARN this was previously accepted +//~^ ERROR naked functions cannot be inlined pub unsafe extern "C" fn inline_hint() { asm!("", options(noreturn)); } #[naked] #[inline(always)] -//~^ WARN naked functions cannot be inlined -//~| WARN this was previously accepted +//~^ ERROR naked functions cannot be inlined pub unsafe extern "C" fn inline_always() { asm!("", options(noreturn)); } #[naked] #[inline(never)] -//~^ WARN naked functions cannot be inlined -//~| WARN this was previously accepted +//~^ ERROR naked functions cannot be inlined pub unsafe extern "C" fn inline_never() { asm!("", options(noreturn)); } #[naked] #[inline] -//~^ WARN naked functions cannot be inlined -//~| WARN this was previously accepted +//~^ ERROR naked functions cannot be inlined #[inline(always)] -//~^ WARN naked functions cannot be inlined -//~| WARN this was previously accepted +//~^ ERROR naked functions cannot be inlined #[inline(never)] -//~^ WARN naked functions cannot be inlined -//~| WARN this was previously accepted +//~^ ERROR naked functions cannot be inlined pub unsafe extern "C" fn inline_all() { asm!("", options(noreturn)); } diff --git a/src/test/ui/asm/naked-functions.stderr b/src/test/ui/asm/naked-functions.stderr index c2dfe443d6038..153858fd982e1 100644 --- a/src/test/ui/asm/naked-functions.stderr +++ b/src/test/ui/asm/naked-functions.stderr @@ -1,5 +1,5 @@ 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)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ @@ -29,66 +29,54 @@ LL | P { x, y }: P, | ^^^^^^^^^^ 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 | ^ | = 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 | LL | / pub unsafe extern "C" fn inc(a: u32) -> u32 { LL | | -LL | | LL | | a + 1 | | ----- non-asm is unsupported in naked functions 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 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)); | ^ | = help: follow the calling convention in asm block to use parameters -warning: only `const` and `sym` operands are supported in naked functions - --> $DIR/naked-functions.rs:43:23 +error[E0787]: only `const` and `sym` operands are supported in naked functions + --> $DIR/naked-functions.rs:42:23 | 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 -warning: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:50:1 +error[E0787]: naked functions must contain a single asm block + --> $DIR/naked-functions.rs:48:1 | LL | / pub unsafe extern "C" fn inc_closure(a: u32) -> u32 { LL | | -LL | | LL | | (|| a + 1)() | | ------------ non-asm is unsupported in naked functions 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 -warning: only `const` and `sym` operands are supported in naked functions - --> $DIR/naked-functions.rs:70:10 +error[E0787]: only `const` and `sym` operands are supported in naked functions + --> $DIR/naked-functions.rs:65:10 | LL | in(reg) a, | ^^^^^^^^^ -... +LL | LL | inlateout(reg) b, | ^^^^^^^^^^^^^^^^ LL | inout(reg) c, @@ -97,31 +85,24 @@ LL | lateout(reg) d, | ^^^^^^^^^^^^^^ 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 -warning: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:67:5 +error[E0787]: asm in naked functions must use `noreturn` option + --> $DIR/naked-functions.rs:63:5 | LL | / asm!("/* {0} {1} {2} {3} {4} {5} {6} */", LL | | -LL | | LL | | in(reg) a, +LL | | ... | LL | | sym G, 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 -warning: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:57:1 +error[E0787]: naked functions must contain a single asm block + --> $DIR/naked-functions.rs:54:1 | LL | / pub unsafe extern "C" fn unsupported_operands() { LL | | -LL | | LL | | let mut a = 0usize; | | ------------------- non-asm is unsupported in naked functions LL | | let mut b = 0usize; @@ -136,123 +117,90 @@ LL | | let mut e = 0usize; 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 -warning: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:83:1 +error[E0787]: naked functions must contain a single asm block + --> $DIR/naked-functions.rs:77:1 | LL | / pub extern "C" fn missing_assembly() { 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 -warning: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:92:5 +error[E0787]: asm in naked functions must use `noreturn` option + --> $DIR/naked-functions.rs:84:5 | 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 -warning: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:95:5 +error[E0787]: asm in naked functions must use `noreturn` option + --> $DIR/naked-functions.rs:86:5 | 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 -warning: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:98:5 +error[E0787]: asm in naked functions must use `noreturn` option + --> $DIR/naked-functions.rs:88:5 | 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 -warning: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:89:1 +error[E0787]: naked functions must contain a single asm block + --> $DIR/naked-functions.rs:82:1 | LL | / pub extern "C" fn too_many_asm_blocks() { LL | | -LL | | LL | | asm!(""); -... | +LL | | LL | | asm!(""); | | -------- multiple asm blocks are unsupported in naked functions -... | +LL | | LL | | asm!(""); | | -------- multiple asm blocks are unsupported in naked functions -... | +LL | | LL | | asm!("", options(noreturn)); | | --------------------------- multiple asm blocks are unsupported in naked functions 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 error: referencing function parameters is not allowed in naked functions - --> $DIR/naked-functions.rs:109:11 + --> $DIR/naked-functions.rs:97:11 | LL | *&y | ^ | = help: follow the calling convention in asm block to use parameters -warning: naked functions must contain a single asm block - --> $DIR/naked-functions.rs:106:5 +error[E0787]: naked functions must contain a single asm block + --> $DIR/naked-functions.rs:95:5 | LL | / pub extern "C" fn inner(y: usize) -> usize { LL | | -LL | | LL | | *&y | | --- 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 -warning: asm options unsupported in naked functions: `nomem`, `preserves_flags` - --> $DIR/naked-functions.rs:117:5 +error[E0787]: asm options unsupported in naked functions: `nomem`, `preserves_flags` + --> $DIR/naked-functions.rs:105:5 | 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 -warning: asm options unsupported in naked functions: `nostack`, `pure`, `readonly` - --> $DIR/naked-functions.rs:124:5 +error[E0787]: asm options unsupported in naked functions: `nostack`, `pure`, `readonly` + --> $DIR/naked-functions.rs:111:5 | 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 -warning: asm in naked functions must use `noreturn` option - --> $DIR/naked-functions.rs:124:5 +error[E0787]: asm in naked functions must use `noreturn` option + --> $DIR/naked-functions.rs:111:5 | 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 warning: Rust ABI is unsupported in naked functions - --> $DIR/naked-functions.rs:133:15 + --> $DIR/naked-functions.rs:118:15 | LL | pub unsafe fn default_abi() { | ^^^^^^^^^^^ @@ -260,64 +208,47 @@ LL | pub unsafe fn default_abi() { = note: `#[warn(undefined_naked_function_abi)]` on by default warning: Rust ABI is unsupported in naked functions - --> $DIR/naked-functions.rs:139:15 + --> $DIR/naked-functions.rs:124:15 | LL | pub unsafe fn rust_abi() { | ^^^^^^^^ -warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:179:1 +error: naked functions cannot be inlined + --> $DIR/naked-functions.rs:164: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 -warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:187:1 +error: naked functions cannot be inlined + --> $DIR/naked-functions.rs:171: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 -warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:195:1 +error: naked functions cannot be inlined + --> $DIR/naked-functions.rs:178: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 -warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:203:1 +error: naked functions cannot be inlined + --> $DIR/naked-functions.rs:185: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 -warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:206:1 +error: naked functions cannot be inlined + --> $DIR/naked-functions.rs:187: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 -warning: naked functions cannot be inlined - --> $DIR/naked-functions.rs:209:1 +error: naked functions cannot be inlined + --> $DIR/naked-functions.rs:189: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 -error: aborting due to 8 previous errors; 23 warnings emitted +error: aborting due to 29 previous errors; 2 warnings emitted +For more information about this error, try `rustc --explain E0787`. From beeba4bcea8151cb43b2e5e45d083700cec4a26f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 21 Jan 2022 00:00:00 +0000 Subject: [PATCH 2/2] Reject may_unwind option in naked functions --- compiler/rustc_passes/src/naked_functions.rs | 1 + src/test/ui/asm/naked-functions.rs | 8 ++++++- src/test/ui/asm/naked-functions.stderr | 24 ++++++++++++-------- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index e4feb8f136c6f..00a93ccc9aa09 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -251,6 +251,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> { } let unsupported_options: Vec<&'static str> = [ + (InlineAsmOptions::MAY_UNWIND, "`may_unwind`"), (InlineAsmOptions::NOMEM, "`nomem`"), (InlineAsmOptions::NOSTACK, "`nostack`"), (InlineAsmOptions::PRESERVES_FLAGS, "`preserves_flags`"), diff --git a/src/test/ui/asm/naked-functions.rs b/src/test/ui/asm/naked-functions.rs index 26397a65cf99a..5b4293972ea21 100644 --- a/src/test/ui/asm/naked-functions.rs +++ b/src/test/ui/asm/naked-functions.rs @@ -5,7 +5,7 @@ #![feature(naked_functions)] #![feature(or_patterns)] -#![feature(asm_const, asm_sym)] +#![feature(asm_const, asm_sym, asm_unwind)] #![crate_type = "lib"] use std::arch::asm; @@ -114,6 +114,12 @@ unsafe extern "C" fn invalid_options_continued() { //~| ERROR asm in naked functions must use `noreturn` option } +#[naked] +unsafe extern "C" fn invalid_may_unwind() { + asm!("", options(noreturn, may_unwind)); + //~^ ERROR asm options unsupported in naked functions: `may_unwind` +} + #[naked] pub unsafe fn default_abi() { //~^ WARN Rust ABI is unsupported in naked functions diff --git a/src/test/ui/asm/naked-functions.stderr b/src/test/ui/asm/naked-functions.stderr index 153858fd982e1..c1dcc433db6c6 100644 --- a/src/test/ui/asm/naked-functions.stderr +++ b/src/test/ui/asm/naked-functions.stderr @@ -199,8 +199,14 @@ error[E0787]: asm in naked functions must use `noreturn` option LL | asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error[E0787]: asm options unsupported in naked functions: `may_unwind` + --> $DIR/naked-functions.rs:119:5 + | +LL | asm!("", options(noreturn, may_unwind)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + warning: Rust ABI is unsupported in naked functions - --> $DIR/naked-functions.rs:118:15 + --> $DIR/naked-functions.rs:124:15 | LL | pub unsafe fn default_abi() { | ^^^^^^^^^^^ @@ -208,47 +214,47 @@ LL | pub unsafe fn default_abi() { = note: `#[warn(undefined_naked_function_abi)]` on by default warning: Rust ABI is unsupported in naked functions - --> $DIR/naked-functions.rs:124:15 + --> $DIR/naked-functions.rs:130:15 | LL | pub unsafe fn rust_abi() { | ^^^^^^^^ error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:164:1 + --> $DIR/naked-functions.rs:170:1 | LL | #[inline] | ^^^^^^^^^ error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:171:1 + --> $DIR/naked-functions.rs:177:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:178:1 + --> $DIR/naked-functions.rs:184:1 | LL | #[inline(never)] | ^^^^^^^^^^^^^^^^ error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:185:1 + --> $DIR/naked-functions.rs:191:1 | LL | #[inline] | ^^^^^^^^^ error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:187:1 + --> $DIR/naked-functions.rs:193:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:189:1 + --> $DIR/naked-functions.rs:195:1 | LL | #[inline(never)] | ^^^^^^^^^^^^^^^^ -error: aborting due to 29 previous errors; 2 warnings emitted +error: aborting due to 30 previous errors; 2 warnings emitted For more information about this error, try `rustc --explain E0787`.