Change InlineAsm to allow multiple targets instead

This commit is contained in:
Gary Guo 2023-12-26 15:28:42 +00:00
parent 7152993aa8
commit b044aaa905
23 changed files with 125 additions and 96 deletions

View file

@ -374,11 +374,17 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
kind: Option<MemoryKind<Self::MemoryKind>>,
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
/// Evaluate the inline assembly.
///
/// 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
/// `InlineAsmOptions::NORETURN` being set.
fn eval_inline_asm(
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
_template: &'tcx [InlineAsmTemplatePiece],
_operands: &[mir::InlineAsmOperand<'tcx>],
_options: InlineAsmOptions,
_targets: &[mir::BasicBlock],
) -> InterpResult<'tcx> {
throw_unsup_format!("inline assembly is not supported")
}

View file

@ -1,6 +1,5 @@
use std::borrow::Cow;
use rustc_ast::ast::InlineAsmOptions;
use rustc_middle::{
mir,
ty::{
@ -224,15 +223,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
terminator.kind
),
InlineAsm { template, ref operands, options, destination, .. } => {
M::eval_inline_asm(self, template, operands, options)?;
if options.contains(InlineAsmOptions::NORETURN) {
throw_ub_custom!(fluent::const_eval_noreturn_asm_returned);
}
self.go_to_block(
destination
.expect("InlineAsm terminators without noreturn must have a destination"),
)
InlineAsm { template, ref operands, options, ref targets, .. } => {
M::eval_inline_asm(self, template, operands, options, targets)?;
}
}

View file

@ -471,9 +471,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
self.check_edge(location, *real_target, EdgeKind::Normal);
self.check_unwind_edge(location, *unwind);
}
TerminatorKind::InlineAsm { destination, unwind, .. } => {
if let Some(destination) = destination {
self.check_edge(location, *destination, EdgeKind::Normal);
TerminatorKind::InlineAsm { targets, unwind, .. } => {
for &target in targets {
self.check_edge(location, target, EdgeKind::Normal);
}
self.check_unwind_edge(location, *unwind);
}