various fixes for naked_asm! implementation

- fix for divergence
- fix error message
- fix another cranelift test
- fix some cranelift things
- don't set the NORETURN option for naked asm
- fix use of naked_asm! in doc comment
- fix use of naked_asm! in run-make test
- use `span_bug` in unreachable branch
This commit is contained in:
Folkert de Vries 2024-09-05 19:45:40 +02:00
parent 10fa482906
commit 5fc60d1e52
29 changed files with 116 additions and 73 deletions

View File

@ -2435,7 +2435,7 @@ pub enum AsmMacro {
} }
impl AsmMacro { impl AsmMacro {
pub const fn macro_name(&self) -> &'static str { pub const fn macro_name(self) -> &'static str {
match self { match self {
AsmMacro::Asm => "asm", AsmMacro::Asm => "asm",
AsmMacro::GlobalAsm => "global_asm", AsmMacro::GlobalAsm => "global_asm",
@ -2443,13 +2443,21 @@ impl AsmMacro {
} }
} }
pub const fn is_supported_option(&self, option: InlineAsmOptions) -> bool { pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
match self { match self {
AsmMacro::Asm => true, AsmMacro::Asm => true,
AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option), AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option), AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
} }
} }
pub const fn diverges(self, options: InlineAsmOptions) -> bool {
match self {
AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
AsmMacro::GlobalAsm => true,
AsmMacro::NakedAsm => true,
}
}
} }
/// Inline assembly. /// Inline assembly.

View File

@ -742,6 +742,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
} }
TerminatorKind::InlineAsm { TerminatorKind::InlineAsm {
asm_macro: _,
template: _, template: _,
operands, operands,
options: _, options: _,

View File

@ -169,6 +169,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> {
} }
} }
TerminatorKind::InlineAsm { TerminatorKind::InlineAsm {
asm_macro: _,
template: _, template: _,
operands, operands,
options: _, options: _,

View File

@ -850,22 +850,13 @@ pub(super) fn expand_naked_asm<'cx>(
return ExpandResult::Retry(()); return ExpandResult::Retry(());
}; };
let expr = match mac { let expr = match mac {
Ok(mut inline_asm) => { Ok(inline_asm) => P(ast::Expr {
// for future compatibility, we always set the NORETURN option.
//
// When we turn `asm!` into `naked_asm!` with this implementation, we can drop
// the `options(noreturn)`, which makes the upgrade smooth when `naked_asm!`
// starts disallowing the `noreturn` option in the future
inline_asm.options |= ast::InlineAsmOptions::NORETURN;
P(ast::Expr {
id: ast::DUMMY_NODE_ID, id: ast::DUMMY_NODE_ID,
kind: ast::ExprKind::InlineAsm(P(inline_asm)), kind: ast::ExprKind::InlineAsm(P(inline_asm)),
span: sp, span: sp,
attrs: ast::AttrVec::new(), attrs: ast::AttrVec::new(),
tokens: None, tokens: None,
}) }),
}
Err(guar) => DummyResult::raw_expr(sp, Some(guar)), Err(guar) => DummyResult::raw_expr(sp, Some(guar)),
}; };
MacEager::expr(expr) MacEager::expr(expr)

View File

@ -726,6 +726,12 @@ pub macro global_asm() {
/* compiler built-in */ /* compiler built-in */
} }
#[rustc_builtin_macro]
#[rustc_macro_transparency = "semitransparent"]
pub macro naked_asm() {
/* compiler built-in */
}
pub static A_STATIC: u8 = 42; pub static A_STATIC: u8 = 42;
#[lang = "panic_location"] #[lang = "panic_location"]

View File

@ -390,7 +390,7 @@ global_asm! {
#[naked] #[naked]
extern "C" fn naked_test() { extern "C" fn naked_test() {
unsafe { unsafe {
asm!("ret", options(noreturn)); naked_asm!("ret");
} }
} }

View File

@ -8,6 +8,7 @@ use rustc_ast::InlineAsmOptions;
use rustc_codegen_ssa::base::is_call_from_compiler_builtins_to_upstream_monomorphization; use rustc_codegen_ssa::base::is_call_from_compiler_builtins_to_upstream_monomorphization;
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::InlineAsmMacro;
use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::TypeVisitableExt;
use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::layout::FnAbiOf;
@ -57,6 +58,7 @@ pub(crate) fn codegen_fn<'tcx>(
match &mir.basic_blocks[START_BLOCK].terminator().kind { match &mir.basic_blocks[START_BLOCK].terminator().kind {
TerminatorKind::InlineAsm { TerminatorKind::InlineAsm {
asm_macro: InlineAsmMacro::NakedAsm,
template, template,
operands, operands,
options, options,
@ -498,6 +500,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
"tail calls are not yet supported in `rustc_codegen_cranelift` backend" "tail calls are not yet supported in `rustc_codegen_cranelift` backend"
), ),
TerminatorKind::InlineAsm { TerminatorKind::InlineAsm {
asm_macro: _,
template, template,
operands, operands,
options, options,

View File

@ -3,7 +3,9 @@ use std::cmp;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTerminateReason}; use rustc_middle::mir::{
self, AssertKind, BasicBlock, InlineAsmMacro, SwitchTargets, UnwindTerminateReason,
};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::ty::{self, Instance, Ty};
@ -1133,6 +1135,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&mut self, &mut self,
helper: TerminatorCodegenHelper<'tcx>, helper: TerminatorCodegenHelper<'tcx>,
bx: &mut Bx, bx: &mut Bx,
asm_macro: InlineAsmMacro,
terminator: &mir::Terminator<'tcx>, terminator: &mir::Terminator<'tcx>,
template: &[ast::InlineAsmTemplatePiece], template: &[ast::InlineAsmTemplatePiece],
operands: &[mir::InlineAsmOperand<'tcx>], operands: &[mir::InlineAsmOperand<'tcx>],
@ -1203,11 +1206,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&operands, &operands,
options, options,
line_spans, line_spans,
if options.contains(InlineAsmOptions::NORETURN) { if asm_macro.diverges(options) { None } else { targets.get(0).copied() },
None
} else {
targets.get(0).copied()
},
unwind, unwind,
instance, instance,
mergeable_succ, mergeable_succ,
@ -1381,6 +1380,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
mir::TerminatorKind::InlineAsm { mir::TerminatorKind::InlineAsm {
asm_macro,
template, template,
ref operands, ref operands,
options, options,
@ -1390,6 +1390,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} => self.codegen_asm_terminator( } => self.codegen_asm_terminator(
helper, helper,
bx, bx,
asm_macro,
terminator, terminator,
template, template,
operands, operands,

View File

@ -395,7 +395,7 @@ pub trait Machine<'tcx>: Sized {
/// ///
/// This should take care of jumping to the next block (one of `targets`) when asm goto /// This should take care of jumping to the next block (one of `targets`) when asm goto
/// is triggered, `targets[0]` when the assembly falls through, or diverge in case of /// is triggered, `targets[0]` when the assembly falls through, or diverge in case of
/// `InlineAsmOptions::NORETURN` being set. /// naked_asm! or `InlineAsmOptions::NORETURN` being set.
fn eval_inline_asm( fn eval_inline_asm(
_ecx: &mut InterpCx<'tcx, Self>, _ecx: &mut InterpCx<'tcx, Self>,
_template: &'tcx [InlineAsmTemplatePiece], _template: &'tcx [InlineAsmTemplatePiece],

View File

@ -3507,11 +3507,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
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 = match asm.asm_macro { let mut diverge = asm.asm_macro.diverges(asm.options);
rustc_ast::AsmMacro::Asm => asm.options.contains(ast::InlineAsmOptions::NORETURN),
rustc_ast::AsmMacro::GlobalAsm => true,
rustc_ast::AsmMacro::NakedAsm => true,
};
for (op, _op_sp) in asm.operands { for (op, _op_sp) in asm.operands {
match op { match op {

View File

@ -2926,16 +2926,16 @@ declare_lint! {
/// ```rust /// ```rust
/// #![feature(asm_experimental_arch, naked_functions)] /// #![feature(asm_experimental_arch, naked_functions)]
/// ///
/// use std::arch::asm; /// use std::arch::naked_asm;
/// ///
/// #[naked] /// #[naked]
/// pub fn default_abi() -> u32 { /// pub fn default_abi() -> u32 {
/// unsafe { asm!("", options(noreturn)); } /// unsafe { naked_asm!(""); }
/// } /// }
/// ///
/// #[naked] /// #[naked]
/// pub extern "Rust" fn rust_abi() -> u32 { /// pub extern "Rust" fn rust_abi() -> u32 {
/// unsafe { asm!("", options(noreturn)); } /// unsafe { naked_asm!(""); }
/// } /// }
/// ``` /// ```
/// ///

View File

@ -4,7 +4,7 @@ use std::fs;
use std::io::{self, Write as _}; use std::io::{self, Write as _};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_ast::InlineAsmTemplatePiece;
use rustc_middle::mir::interpret::{ use rustc_middle::mir::interpret::{
AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer, Provenance, alloc_range, AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer, Provenance, alloc_range,
read_target_uint, read_target_uint,
@ -1024,9 +1024,9 @@ impl<'tcx> TerminatorKind<'tcx> {
vec!["real".into(), "unwind".into()] vec!["real".into(), "unwind".into()]
} }
FalseUnwind { unwind: _, .. } => vec!["real".into()], FalseUnwind { unwind: _, .. } => vec!["real".into()],
InlineAsm { options, ref targets, unwind, .. } => { InlineAsm { asm_macro, options, ref targets, unwind, .. } => {
let mut vec = Vec::with_capacity(targets.len() + 1); let mut vec = Vec::with_capacity(targets.len() + 1);
if !options.contains(InlineAsmOptions::NORETURN) { if !asm_macro.diverges(options) {
vec.push("return".into()); vec.push("return".into());
} }
vec.resize(targets.len(), "label".into()); vec.resize(targets.len(), "label".into());

View File

@ -605,6 +605,25 @@ impl CallSource {
} }
} }
#[derive(Clone, Copy, Debug, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
#[derive(TypeFoldable, TypeVisitable)]
/// The macro that an inline assembly block was created by
pub enum InlineAsmMacro {
/// The `asm!` macro
Asm,
/// The `naked_asm!` macro
NakedAsm,
}
impl InlineAsmMacro {
pub const fn diverges(self, options: InlineAsmOptions) -> bool {
match self {
InlineAsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
InlineAsmMacro::NakedAsm => true,
}
}
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Terminators // Terminators
@ -859,6 +878,9 @@ pub enum TerminatorKind<'tcx> {
/// Block ends with an inline assembly block. This is a terminator since /// Block ends with an inline assembly block. This is a terminator since
/// inline assembly is allowed to diverge. /// inline assembly is allowed to diverge.
InlineAsm { InlineAsm {
/// Macro used to create this inline asm: one of `asm!` or `naked_asm!`
asm_macro: InlineAsmMacro,
/// The template for the inline assembly, with placeholders. /// The template for the inline assembly, with placeholders.
template: &'tcx [InlineAsmTemplatePiece], template: &'tcx [InlineAsmTemplatePiece],
@ -874,7 +896,7 @@ pub enum TerminatorKind<'tcx> {
/// Valid targets for the inline assembly. /// Valid targets for the inline assembly.
/// The first element is the fallthrough destination, unless /// The first element is the fallthrough destination, unless
/// InlineAsmOptions::NORETURN is set. /// asm_macro == InlineAsmMacro::NakedAsm or InlineAsmOptions::NORETURN is set.
targets: Box<[BasicBlock]>, targets: Box<[BasicBlock]>,
/// Action to be taken if the inline assembly unwinds. This is present /// Action to be taken if the inline assembly unwinds. This is present

View File

@ -666,6 +666,7 @@ impl<'tcx> TerminatorKind<'tcx> {
}, },
InlineAsm { InlineAsm {
asm_macro: _,
template: _, template: _,
ref operands, ref operands,
options: _, options: _,

View File

@ -576,6 +576,7 @@ macro_rules! make_mir_visitor {
} }
TerminatorKind::InlineAsm { TerminatorKind::InlineAsm {
asm_macro: _,
template: _, template: _,
operands, operands,
options: _, options: _,

View File

@ -12,7 +12,7 @@ use std::cmp::Ordering;
use std::fmt; use std::fmt;
use std::ops::Index; use std::ops::Index;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd}; use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
@ -173,6 +173,7 @@ pub struct ClosureExpr<'tcx> {
#[derive(Clone, Debug, HashStable)] #[derive(Clone, Debug, HashStable)]
pub struct InlineAsmExpr<'tcx> { pub struct InlineAsmExpr<'tcx> {
pub asm_macro: AsmMacro,
pub template: &'tcx [InlineAsmTemplatePiece], pub template: &'tcx [InlineAsmTemplatePiece],
pub operands: Box<[InlineAsmOperand<'tcx>]>, pub operands: Box<[InlineAsmOperand<'tcx>]>,
pub options: InlineAsmOptions, pub options: InlineAsmOptions,

View File

@ -148,7 +148,13 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
NamedConst { def_id: _, args: _, user_ty: _ } => {} NamedConst { def_id: _, args: _, user_ty: _ } => {}
ConstParam { param: _, def_id: _ } => {} ConstParam { param: _, def_id: _ } => {}
StaticRef { alloc_id: _, ty: _, def_id: _ } => {} StaticRef { alloc_id: _, ty: _, def_id: _ } => {}
InlineAsm(box InlineAsmExpr { ref operands, template: _, options: _, line_spans: _ }) => { InlineAsm(box InlineAsmExpr {
asm_macro: _,
ref operands,
template: _,
options: _,
line_spans: _,
}) => {
for op in &**operands { for op in &**operands {
use InlineAsmOperand::*; use InlineAsmOperand::*;
match op { match op {

View File

@ -2,7 +2,7 @@
use std::iter; use std::iter;
use rustc_ast::InlineAsmOptions; use rustc_ast::{AsmMacro, InlineAsmOptions};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir as hir; use rustc_hir as hir;
@ -384,6 +384,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
block.unit() block.unit()
} }
ExprKind::InlineAsm(box InlineAsmExpr { ExprKind::InlineAsm(box InlineAsmExpr {
asm_macro,
template, template,
ref operands, ref operands,
options, options,
@ -392,11 +393,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
use rustc_middle::{mir, thir}; use rustc_middle::{mir, thir};
let destination_block = this.cfg.start_new_block(); let destination_block = this.cfg.start_new_block();
let mut targets = if options.contains(InlineAsmOptions::NORETURN) { let mut targets =
vec![] if asm_macro.diverges(options) { vec![] } else { vec![destination_block] };
} else {
vec![destination_block]
};
let operands = operands let operands = operands
.into_iter() .into_iter()
@ -474,7 +472,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
this.cfg.push_assign_unit(block, source_info, destination, this.tcx); this.cfg.push_assign_unit(block, source_info, destination, this.tcx);
} }
let asm_macro = match asm_macro {
AsmMacro::Asm => InlineAsmMacro::Asm,
AsmMacro::GlobalAsm => {
span_bug!(expr_span, "unexpected global_asm! in inline asm")
}
AsmMacro::NakedAsm => InlineAsmMacro::NakedAsm,
};
this.cfg.terminate(block, source_info, TerminatorKind::InlineAsm { this.cfg.terminate(block, source_info, TerminatorKind::InlineAsm {
asm_macro,
template, template,
operands, operands,
options, options,

View File

@ -672,6 +672,7 @@ impl<'tcx> Cx<'tcx> {
} }
hir::ExprKind::InlineAsm(asm) => ExprKind::InlineAsm(Box::new(InlineAsmExpr { hir::ExprKind::InlineAsm(asm) => ExprKind::InlineAsm(Box::new(InlineAsmExpr {
asm_macro: asm.asm_macro,
template: asm.template, template: asm.template,
operands: asm operands: asm
.operands .operands

View File

@ -818,10 +818,12 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
} }
fn print_inline_asm_expr(&mut self, expr: &InlineAsmExpr<'tcx>, depth_lvl: usize) { fn print_inline_asm_expr(&mut self, expr: &InlineAsmExpr<'tcx>, depth_lvl: usize) {
let InlineAsmExpr { template, operands, options, line_spans } = expr; let InlineAsmExpr { asm_macro, template, operands, options, line_spans } = expr;
print_indented!(self, "InlineAsmExpr {", depth_lvl); print_indented!(self, "InlineAsmExpr {", depth_lvl);
print_indented!(self, format!("asm_macro: {:?}", asm_macro), depth_lvl + 1);
print_indented!(self, "template: [", depth_lvl + 1); print_indented!(self, "template: [", depth_lvl + 1);
for template_piece in template.iter() { for template_piece in template.iter() {
print_indented!(self, format!("{:?}", template_piece), depth_lvl + 2); print_indented!(self, format!("{:?}", template_piece), depth_lvl + 2);

View File

@ -481,6 +481,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
} }
} }
TerminatorKind::InlineAsm { TerminatorKind::InlineAsm {
asm_macro: _,
template: _, template: _,
ref operands, ref operands,
options: _, options: _,

View File

@ -499,7 +499,7 @@ passes_naked_functions_incompatible_attribute =
passes_naked_functions_must_naked_asm = passes_naked_functions_must_naked_asm =
the `asm!` macro is not allowed in naked functions the `asm!` macro is not allowed in naked functions
.suggestion = consider using the `naked_asm!` macro instead .label = consider using the `naked_asm!` macro instead
passes_no_link = passes_no_link =
attribute should be applied to an `extern crate` item attribute should be applied to an `extern crate` item

View File

@ -1190,9 +1190,8 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for NakedFunctionsAsmBlock {
#[diag(passes_naked_functions_must_naked_asm, code = E0787)] #[diag(passes_naked_functions_must_naked_asm, code = E0787)]
pub(crate) struct NakedFunctionsMustNakedAsm { pub(crate) struct NakedFunctionsMustNakedAsm {
#[primary_span] #[primary_span]
#[label]
pub span: Span, pub span: Span,
#[suggestion(code = "naked_asm!", applicability = "machine-applicable")]
pub macro_span: Span,
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]

View File

@ -7,10 +7,11 @@ use rustc_hir::intravisit::Visitor;
use rustc_hir::{ExprKind, HirIdSet, StmtKind}; use rustc_hir::{ExprKind, HirIdSet, StmtKind};
use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::hir::nested_filter::OnlyBodies;
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::span_bug;
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::{
@ -137,10 +138,7 @@ fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<
ItemKind::InlineAsm => { ItemKind::InlineAsm => {
has_err = true; has_err = true;
// the span that contains the `asm!` call, tcx.dcx().emit_err(NakedFunctionsMustNakedAsm { span });
// 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;
@ -210,8 +208,7 @@ impl CheckInlineAssembly {
self.items.push((ItemKind::NonAsm, span)); self.items.push((ItemKind::NonAsm, span));
} }
ExprKind::InlineAsm(asm) => { ExprKind::InlineAsm(asm) => match asm.asm_macro {
match asm.asm_macro {
rustc_ast::AsmMacro::Asm => { rustc_ast::AsmMacro::Asm => {
self.items.push((ItemKind::InlineAsm, span)); self.items.push((ItemKind::InlineAsm, span));
} }
@ -219,10 +216,9 @@ impl CheckInlineAssembly {
self.items.push((ItemKind::NakedAsm, span)); self.items.push((ItemKind::NakedAsm, span));
} }
rustc_ast::AsmMacro::GlobalAsm => { rustc_ast::AsmMacro::GlobalAsm => {
// not allowed in this position span_bug!(span, "`global_asm!` is not allowed in this position")
}
}
} }
},
ExprKind::DropTemps(..) | ExprKind::Block(..) => { ExprKind::DropTemps(..) | ExprKind::Block(..) => {
hir::intravisit::walk_expr(self, expr); hir::intravisit::walk_expr(self, expr);

View File

@ -655,6 +655,7 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
} }
} }
mir::TerminatorKind::InlineAsm { mir::TerminatorKind::InlineAsm {
asm_macro: _,
template, template,
operands, operands,
options, options,

View File

@ -1,5 +1,5 @@
use rustc_ast::ast; use rustc_ast::ast;
use rustc_builtin_macros::asm::{parse_asm_args, AsmArgs}; use rustc_builtin_macros::asm::{AsmArgs, parse_asm_args};
use crate::rewrite::RewriteContext; use crate::rewrite::RewriteContext;

View File

@ -14,7 +14,7 @@
#[no_mangle] #[no_mangle]
pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) { pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) {
unsafe { unsafe {
core::arch::asm!("ud2", options(noreturn)); core::arch::naked_asm!("ud2");
} }
} }

View File

@ -72,7 +72,7 @@ extern "C" fn vanilla_weak_linkage() -> u32 {
#[cfg(not(windows))] #[cfg(not(windows))]
#[linkage = "weak"] #[linkage = "weak"]
extern "C" fn naked_weak_linkage() -> u32 { extern "C" fn naked_weak_linkage() -> u32 {
unsafe { naked_asm!("mov rax, 42", "ret", options(noreturn)) } unsafe { naked_asm!("mov rax, 42", "ret") }
} }
// functions that are declared in an `extern "C"` block are currently not exported // functions that are declared in an `extern "C"` block are currently not exported

View File

@ -74,9 +74,7 @@ error[E0787]: the `asm!` macro is not allowed in naked functions
--> $DIR/naked-functions.rs:13:5 --> $DIR/naked-functions.rs:13:5
| |
LL | asm!("", options(raw)); LL | asm!("", options(raw));
| ----^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^ consider using the `naked_asm!` macro instead
| |
| 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:25:5 --> $DIR/naked-functions.rs:25:5