Skip to content

Commit 5fc60d1

Browse files
committed
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
1 parent 10fa482 commit 5fc60d1

File tree

29 files changed

+116
-73
lines changed

29 files changed

+116
-73
lines changed

compiler/rustc_ast/src/ast.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -2435,21 +2435,29 @@ pub enum AsmMacro {
24352435
}
24362436

24372437
impl AsmMacro {
2438-
pub const fn macro_name(&self) -> &'static str {
2438+
pub const fn macro_name(self) -> &'static str {
24392439
match self {
24402440
AsmMacro::Asm => "asm",
24412441
AsmMacro::GlobalAsm => "global_asm",
24422442
AsmMacro::NakedAsm => "naked_asm",
24432443
}
24442444
}
24452445

2446-
pub const fn is_supported_option(&self, option: InlineAsmOptions) -> bool {
2446+
pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
24472447
match self {
24482448
AsmMacro::Asm => true,
24492449
AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
24502450
AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
24512451
}
24522452
}
2453+
2454+
pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2455+
match self {
2456+
AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2457+
AsmMacro::GlobalAsm => true,
2458+
AsmMacro::NakedAsm => true,
2459+
}
2460+
}
24532461
}
24542462

24552463
/// Inline assembly.

compiler/rustc_borrowck/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
742742
}
743743

744744
TerminatorKind::InlineAsm {
745+
asm_macro: _,
745746
template: _,
746747
operands,
747748
options: _,

compiler/rustc_borrowck/src/polonius/loan_invalidations.rs

+1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> {
169169
}
170170
}
171171
TerminatorKind::InlineAsm {
172+
asm_macro: _,
172173
template: _,
173174
operands,
174175
options: _,

compiler/rustc_builtin_macros/src/asm.rs

+7-16
Original file line numberDiff line numberDiff line change
@@ -850,22 +850,13 @@ pub(super) fn expand_naked_asm<'cx>(
850850
return ExpandResult::Retry(());
851851
};
852852
let expr = match mac {
853-
Ok(mut inline_asm) => {
854-
// for future compatibility, we always set the NORETURN option.
855-
//
856-
// When we turn `asm!` into `naked_asm!` with this implementation, we can drop
857-
// the `options(noreturn)`, which makes the upgrade smooth when `naked_asm!`
858-
// starts disallowing the `noreturn` option in the future
859-
inline_asm.options |= ast::InlineAsmOptions::NORETURN;
860-
861-
P(ast::Expr {
862-
id: ast::DUMMY_NODE_ID,
863-
kind: ast::ExprKind::InlineAsm(P(inline_asm)),
864-
span: sp,
865-
attrs: ast::AttrVec::new(),
866-
tokens: None,
867-
})
868-
}
853+
Ok(inline_asm) => P(ast::Expr {
854+
id: ast::DUMMY_NODE_ID,
855+
kind: ast::ExprKind::InlineAsm(P(inline_asm)),
856+
span: sp,
857+
attrs: ast::AttrVec::new(),
858+
tokens: None,
859+
}),
869860
Err(guar) => DummyResult::raw_expr(sp, Some(guar)),
870861
};
871862
MacEager::expr(expr)

compiler/rustc_codegen_cranelift/example/mini_core.rs

+6
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,12 @@ pub macro global_asm() {
726726
/* compiler built-in */
727727
}
728728

729+
#[rustc_builtin_macro]
730+
#[rustc_macro_transparency = "semitransparent"]
731+
pub macro naked_asm() {
732+
/* compiler built-in */
733+
}
734+
729735
pub static A_STATIC: u8 = 42;
730736

731737
#[lang = "panic_location"]

compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ global_asm! {
390390
#[naked]
391391
extern "C" fn naked_test() {
392392
unsafe {
393-
asm!("ret", options(noreturn));
393+
naked_asm!("ret");
394394
}
395395
}
396396

compiler/rustc_codegen_cranelift/src/base.rs

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_ast::InlineAsmOptions;
88
use rustc_codegen_ssa::base::is_call_from_compiler_builtins_to_upstream_monomorphization;
99
use rustc_index::IndexVec;
1010
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
11+
use rustc_middle::mir::InlineAsmMacro;
1112
use rustc_middle::ty::TypeVisitableExt;
1213
use rustc_middle::ty::adjustment::PointerCoercion;
1314
use rustc_middle::ty::layout::FnAbiOf;
@@ -57,6 +58,7 @@ pub(crate) fn codegen_fn<'tcx>(
5758

5859
match &mir.basic_blocks[START_BLOCK].terminator().kind {
5960
TerminatorKind::InlineAsm {
61+
asm_macro: InlineAsmMacro::NakedAsm,
6062
template,
6163
operands,
6264
options,
@@ -498,6 +500,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
498500
"tail calls are not yet supported in `rustc_codegen_cranelift` backend"
499501
),
500502
TerminatorKind::InlineAsm {
503+
asm_macro: _,
501504
template,
502505
operands,
503506
options,

compiler/rustc_codegen_ssa/src/mir/block.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use std::cmp;
33
use rustc_ast as ast;
44
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
55
use rustc_hir::lang_items::LangItem;
6-
use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTerminateReason};
6+
use rustc_middle::mir::{
7+
self, AssertKind, BasicBlock, InlineAsmMacro, SwitchTargets, UnwindTerminateReason,
8+
};
79
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
810
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
911
use rustc_middle::ty::{self, Instance, Ty};
@@ -1133,6 +1135,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11331135
&mut self,
11341136
helper: TerminatorCodegenHelper<'tcx>,
11351137
bx: &mut Bx,
1138+
asm_macro: InlineAsmMacro,
11361139
terminator: &mir::Terminator<'tcx>,
11371140
template: &[ast::InlineAsmTemplatePiece],
11381141
operands: &[mir::InlineAsmOperand<'tcx>],
@@ -1203,11 +1206,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12031206
&operands,
12041207
options,
12051208
line_spans,
1206-
if options.contains(InlineAsmOptions::NORETURN) {
1207-
None
1208-
} else {
1209-
targets.get(0).copied()
1210-
},
1209+
if asm_macro.diverges(options) { None } else { targets.get(0).copied() },
12111210
unwind,
12121211
instance,
12131212
mergeable_succ,
@@ -1381,6 +1380,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
13811380
}
13821381

13831382
mir::TerminatorKind::InlineAsm {
1383+
asm_macro,
13841384
template,
13851385
ref operands,
13861386
options,
@@ -1390,6 +1390,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
13901390
} => self.codegen_asm_terminator(
13911391
helper,
13921392
bx,
1393+
asm_macro,
13931394
terminator,
13941395
template,
13951396
operands,

compiler/rustc_const_eval/src/interpret/machine.rs

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

compiler/rustc_hir_typeck/src/expr.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -3507,11 +3507,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
35073507
}
35083508

35093509
fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>) -> Ty<'tcx> {
3510-
let mut diverge = match asm.asm_macro {
3511-
rustc_ast::AsmMacro::Asm => asm.options.contains(ast::InlineAsmOptions::NORETURN),
3512-
rustc_ast::AsmMacro::GlobalAsm => true,
3513-
rustc_ast::AsmMacro::NakedAsm => true,
3514-
};
3510+
let mut diverge = asm.asm_macro.diverges(asm.options);
35153511

35163512
for (op, _op_sp) in asm.operands {
35173513
match op {

compiler/rustc_lint_defs/src/builtin.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2926,16 +2926,16 @@ declare_lint! {
29262926
/// ```rust
29272927
/// #![feature(asm_experimental_arch, naked_functions)]
29282928
///
2929-
/// use std::arch::asm;
2929+
/// use std::arch::naked_asm;
29302930
///
29312931
/// #[naked]
29322932
/// pub fn default_abi() -> u32 {
2933-
/// unsafe { asm!("", options(noreturn)); }
2933+
/// unsafe { naked_asm!(""); }
29342934
/// }
29352935
///
29362936
/// #[naked]
29372937
/// pub extern "Rust" fn rust_abi() -> u32 {
2938-
/// unsafe { asm!("", options(noreturn)); }
2938+
/// unsafe { naked_asm!(""); }
29392939
/// }
29402940
/// ```
29412941
///

compiler/rustc_middle/src/mir/pretty.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::fs;
44
use std::io::{self, Write as _};
55
use std::path::{Path, PathBuf};
66

7-
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
7+
use rustc_ast::InlineAsmTemplatePiece;
88
use rustc_middle::mir::interpret::{
99
AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer, Provenance, alloc_range,
1010
read_target_uint,
@@ -1024,9 +1024,9 @@ impl<'tcx> TerminatorKind<'tcx> {
10241024
vec!["real".into(), "unwind".into()]
10251025
}
10261026
FalseUnwind { unwind: _, .. } => vec!["real".into()],
1027-
InlineAsm { options, ref targets, unwind, .. } => {
1027+
InlineAsm { asm_macro, options, ref targets, unwind, .. } => {
10281028
let mut vec = Vec::with_capacity(targets.len() + 1);
1029-
if !options.contains(InlineAsmOptions::NORETURN) {
1029+
if !asm_macro.diverges(options) {
10301030
vec.push("return".into());
10311031
}
10321032
vec.resize(targets.len(), "label".into());

compiler/rustc_middle/src/mir/syntax.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,25 @@ impl CallSource {
605605
}
606606
}
607607

608+
#[derive(Clone, Copy, Debug, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
609+
#[derive(TypeFoldable, TypeVisitable)]
610+
/// The macro that an inline assembly block was created by
611+
pub enum InlineAsmMacro {
612+
/// The `asm!` macro
613+
Asm,
614+
/// The `naked_asm!` macro
615+
NakedAsm,
616+
}
617+
618+
impl InlineAsmMacro {
619+
pub const fn diverges(self, options: InlineAsmOptions) -> bool {
620+
match self {
621+
InlineAsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
622+
InlineAsmMacro::NakedAsm => true,
623+
}
624+
}
625+
}
626+
608627
///////////////////////////////////////////////////////////////////////////
609628
// Terminators
610629

@@ -859,6 +878,9 @@ pub enum TerminatorKind<'tcx> {
859878
/// Block ends with an inline assembly block. This is a terminator since
860879
/// inline assembly is allowed to diverge.
861880
InlineAsm {
881+
/// Macro used to create this inline asm: one of `asm!` or `naked_asm!`
882+
asm_macro: InlineAsmMacro,
883+
862884
/// The template for the inline assembly, with placeholders.
863885
template: &'tcx [InlineAsmTemplatePiece],
864886

@@ -874,7 +896,7 @@ pub enum TerminatorKind<'tcx> {
874896

875897
/// Valid targets for the inline assembly.
876898
/// The first element is the fallthrough destination, unless
877-
/// InlineAsmOptions::NORETURN is set.
899+
/// asm_macro == InlineAsmMacro::NakedAsm or InlineAsmOptions::NORETURN is set.
878900
targets: Box<[BasicBlock]>,
879901

880902
/// Action to be taken if the inline assembly unwinds. This is present

compiler/rustc_middle/src/mir/terminator.rs

+1
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ impl<'tcx> TerminatorKind<'tcx> {
666666
},
667667

668668
InlineAsm {
669+
asm_macro: _,
669670
template: _,
670671
ref operands,
671672
options: _,

compiler/rustc_middle/src/mir/visit.rs

+1
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,7 @@ macro_rules! make_mir_visitor {
576576
}
577577

578578
TerminatorKind::InlineAsm {
579+
asm_macro: _,
579580
template: _,
580581
operands,
581582
options: _,

compiler/rustc_middle/src/thir.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::cmp::Ordering;
1212
use std::fmt;
1313
use std::ops::Index;
1414

15-
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
15+
use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece};
1616
use rustc_hir as hir;
1717
use rustc_hir::def_id::DefId;
1818
use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
@@ -173,6 +173,7 @@ pub struct ClosureExpr<'tcx> {
173173

174174
#[derive(Clone, Debug, HashStable)]
175175
pub struct InlineAsmExpr<'tcx> {
176+
pub asm_macro: AsmMacro,
176177
pub template: &'tcx [InlineAsmTemplatePiece],
177178
pub operands: Box<[InlineAsmOperand<'tcx>]>,
178179
pub options: InlineAsmOptions,

compiler/rustc_middle/src/thir/visit.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,13 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
148148
NamedConst { def_id: _, args: _, user_ty: _ } => {}
149149
ConstParam { param: _, def_id: _ } => {}
150150
StaticRef { alloc_id: _, ty: _, def_id: _ } => {}
151-
InlineAsm(box InlineAsmExpr { ref operands, template: _, options: _, line_spans: _ }) => {
151+
InlineAsm(box InlineAsmExpr {
152+
asm_macro: _,
153+
ref operands,
154+
template: _,
155+
options: _,
156+
line_spans: _,
157+
}) => {
152158
for op in &**operands {
153159
use InlineAsmOperand::*;
154160
match op {

compiler/rustc_mir_build/src/build/expr/into.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use std::iter;
44

5-
use rustc_ast::InlineAsmOptions;
5+
use rustc_ast::{AsmMacro, InlineAsmOptions};
66
use rustc_data_structures::fx::FxHashMap;
77
use rustc_data_structures::stack::ensure_sufficient_stack;
88
use rustc_hir as hir;
@@ -384,6 +384,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
384384
block.unit()
385385
}
386386
ExprKind::InlineAsm(box InlineAsmExpr {
387+
asm_macro,
387388
template,
388389
ref operands,
389390
options,
@@ -392,11 +393,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
392393
use rustc_middle::{mir, thir};
393394

394395
let destination_block = this.cfg.start_new_block();
395-
let mut targets = if options.contains(InlineAsmOptions::NORETURN) {
396-
vec![]
397-
} else {
398-
vec![destination_block]
399-
};
396+
let mut targets =
397+
if asm_macro.diverges(options) { vec![] } else { vec![destination_block] };
400398

401399
let operands = operands
402400
.into_iter()
@@ -474,7 +472,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
474472
this.cfg.push_assign_unit(block, source_info, destination, this.tcx);
475473
}
476474

475+
let asm_macro = match asm_macro {
476+
AsmMacro::Asm => InlineAsmMacro::Asm,
477+
AsmMacro::GlobalAsm => {
478+
span_bug!(expr_span, "unexpected global_asm! in inline asm")
479+
}
480+
AsmMacro::NakedAsm => InlineAsmMacro::NakedAsm,
481+
};
482+
477483
this.cfg.terminate(block, source_info, TerminatorKind::InlineAsm {
484+
asm_macro,
478485
template,
479486
operands,
480487
options,

compiler/rustc_mir_build/src/thir/cx/expr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,7 @@ impl<'tcx> Cx<'tcx> {
672672
}
673673

674674
hir::ExprKind::InlineAsm(asm) => ExprKind::InlineAsm(Box::new(InlineAsmExpr {
675+
asm_macro: asm.asm_macro,
675676
template: asm.template,
676677
operands: asm
677678
.operands

compiler/rustc_mir_build/src/thir/print.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -818,10 +818,12 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
818818
}
819819

820820
fn print_inline_asm_expr(&mut self, expr: &InlineAsmExpr<'tcx>, depth_lvl: usize) {
821-
let InlineAsmExpr { template, operands, options, line_spans } = expr;
821+
let InlineAsmExpr { asm_macro, template, operands, options, line_spans } = expr;
822822

823823
print_indented!(self, "InlineAsmExpr {", depth_lvl);
824824

825+
print_indented!(self, format!("asm_macro: {:?}", asm_macro), depth_lvl + 1);
826+
825827
print_indented!(self, "template: [", depth_lvl + 1);
826828
for template_piece in template.iter() {
827829
print_indented!(self, format!("{:?}", template_piece), depth_lvl + 2);

0 commit comments

Comments
 (0)