Skip to content

Commit 7a0922c

Browse files
committed
fix for divergence
1 parent be6b3c1 commit 7a0922c

File tree

18 files changed

+79
-28
lines changed

18 files changed

+79
-28
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2429,21 +2429,29 @@ pub enum AsmMacro {
24292429
}
24302430

24312431
impl AsmMacro {
2432-
pub const fn macro_name(&self) -> &'static str {
2432+
pub const fn macro_name(self) -> &'static str {
24332433
match self {
24342434
AsmMacro::Asm => "asm",
24352435
AsmMacro::GlobalAsm => "global_asm",
24362436
AsmMacro::NakedAsm => "naked_asm",
24372437
}
24382438
}
24392439

2440-
pub const fn is_supported_option(&self, option: InlineAsmOptions) -> bool {
2440+
pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
24412441
match self {
24422442
AsmMacro::Asm => true,
24432443
AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
24442444
AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
24452445
}
24462446
}
2447+
2448+
pub const fn diverges(self, options: InlineAsmOptions) -> bool {
2449+
match self {
2450+
AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
2451+
AsmMacro::GlobalAsm => true,
2452+
AsmMacro::NakedAsm => true,
2453+
}
2454+
}
24472455
}
24482456

24492457
/// Inline assembly.

compiler/rustc_borrowck/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,7 @@ impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
742742
}
743743

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

compiler/rustc_borrowck/src/polonius/loan_invalidations.rs

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

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
498498
"tail calls are not yet supported in `rustc_codegen_cranelift` backend"
499499
),
500500
TerminatorKind::InlineAsm {
501+
asm_macro,
501502
template,
502503
operands,
503504
options,
@@ -512,7 +513,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
512513
);
513514
}
514515

515-
let have_labels = if options.contains(InlineAsmOptions::NORETURN) {
516+
let have_labels = if asm_macro.diverges(options) {
516517
!targets.is_empty()
517518
} else {
518519
targets.len() > 1

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 7 additions & 6 deletions
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};
@@ -1156,6 +1158,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11561158
&mut self,
11571159
helper: TerminatorCodegenHelper<'tcx>,
11581160
bx: &mut Bx,
1161+
asm_macro: InlineAsmMacro,
11591162
terminator: &mir::Terminator<'tcx>,
11601163
template: &[ast::InlineAsmTemplatePiece],
11611164
operands: &[mir::InlineAsmOperand<'tcx>],
@@ -1226,11 +1229,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
12261229
&operands,
12271230
options,
12281231
line_spans,
1229-
if options.contains(InlineAsmOptions::NORETURN) {
1230-
None
1231-
} else {
1232-
targets.get(0).copied()
1233-
},
1232+
if asm_macro.diverges(options) { None } else { targets.get(0).copied() },
12341233
unwind,
12351234
instance,
12361235
mergeable_succ,
@@ -1406,6 +1405,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
14061405
}
14071406

14081407
mir::TerminatorKind::InlineAsm {
1408+
asm_macro,
14091409
template,
14101410
ref operands,
14111411
options,
@@ -1415,6 +1415,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
14151415
} => self.codegen_asm_terminator(
14161416
helper,
14171417
bx,
1418+
asm_macro,
14181419
terminator,
14191420
template,
14201421
operands,

compiler/rustc_const_eval/src/interpret/machine.rs

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

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3307,11 +3307,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
33073307
}
33083308

33093309
fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>) -> Ty<'tcx> {
3310-
let mut diverge = match asm.asm_macro {
3311-
rustc_ast::AsmMacro::Asm => asm.options.contains(ast::InlineAsmOptions::NORETURN),
3312-
rustc_ast::AsmMacro::GlobalAsm => true,
3313-
rustc_ast::AsmMacro::NakedAsm => true,
3314-
};
3310+
let mut diverge = asm.asm_macro.diverges(asm.options);
33153311

33163312
for (op, _op_sp) in asm.operands {
33173313
match op {

compiler/rustc_middle/src/mir/pretty.rs

Lines changed: 3 additions & 3 deletions
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
alloc_range, read_target_uint, AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer,
1010
Provenance,
@@ -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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,25 @@ impl CallSource {
604604
}
605605
}
606606

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

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

@@ -873,7 +895,7 @@ pub enum TerminatorKind<'tcx> {
873895

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

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

compiler/rustc_middle/src/mir/terminator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@ impl<'tcx> TerminatorKind<'tcx> {
655655
},
656656

657657
InlineAsm {
658+
asm_macro: _,
658659
template: _,
659660
ref operands,
660661
options: _,

0 commit comments

Comments
 (0)