diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 00a93ccc9aa..02f6b406059 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -1,7 +1,7 @@ //! Checks validity of naked functions. use rustc_ast::{Attribute, InlineAsmOptions}; -use rustc_errors::struct_span_err; +use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{FnKind, Visitor}; @@ -274,12 +274,25 @@ fn check_inline_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) { } 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(); + struct_span_err!( self.tcx.sess, span, E0787, "asm in naked functions must use `noreturn` option" ) + .span_suggestion( + last_span, + "consider specifying that the asm block is responsible \ + for returning from the function", + String::from(", options(noreturn)"), + Applicability::MachineApplicable, + ) .emit(); } } diff --git a/src/test/ui/asm/naked-functions.stderr b/src/test/ui/asm/naked-functions.stderr index 5520f815f3e..35dc9cca33b 100644 --- a/src/test/ui/asm/naked-functions.stderr +++ b/src/test/ui/asm/naked-functions.stderr @@ -97,6 +97,11 @@ LL | | LL | | sym G, LL | | ); | |_____^ + | +help: consider specifying that the asm block is responsible for returning from the function + | +LL | sym G, options(noreturn), + | +++++++++++++++++++ error[E0787]: naked functions must contain a single asm block --> $DIR/naked-functions.rs:53:1 @@ -131,18 +136,33 @@ error[E0787]: asm in naked functions must use `noreturn` option | LL | asm!(""); | ^^^^^^^^ + | +help: consider specifying that the asm block is responsible for returning from the function + | +LL | asm!("", options(noreturn)); + | +++++++++++++++++++ error[E0787]: asm in naked functions must use `noreturn` option --> $DIR/naked-functions.rs:85:5 | LL | asm!(""); | ^^^^^^^^ + | +help: consider specifying that the asm block is responsible for returning from the function + | +LL | asm!("", options(noreturn)); + | +++++++++++++++++++ error[E0787]: asm in naked functions must use `noreturn` option --> $DIR/naked-functions.rs:87:5 | LL | asm!(""); | ^^^^^^^^ + | +help: consider specifying that the asm block is responsible for returning from the function + | +LL | asm!("", options(noreturn)); + | +++++++++++++++++++ error[E0787]: naked functions must contain a single asm block --> $DIR/naked-functions.rs:81:1 @@ -198,6 +218,11 @@ error[E0787]: asm in naked functions must use `noreturn` option | LL | asm!("", options(readonly, nostack), options(pure)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider specifying that the asm block is responsible for returning from the function + | +LL | asm!("", options(noreturn), options(readonly, nostack), options(pure)); + | +++++++++++++++++++ error[E0787]: asm options unsupported in naked functions: `may_unwind` --> $DIR/naked-functions.rs:118:5