From 3ed1e79cc40133b6cdb65955c7433cc483a89ca8 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Sun, 24 May 2020 02:04:49 +0100 Subject: [PATCH] Properly handle InlineAsmOperand::SymFn when collecting monomorphized items Fixes #72484 --- src/librustc_codegen_ssa/mir/block.rs | 3 +- src/librustc_mir/monomorphize/collector.rs | 11 +++++-- src/test/ui/asm/sym.rs | 38 ++++++++++++++++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/asm/sym.rs diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index b487ed8dea8b6..2a6d1abba9e9d 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -908,13 +908,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::InlineAsmOperand::SymFn { ref value } => { let literal = self.monomorphize(&value.literal); if let ty::FnDef(def_id, substs) = literal.ty.kind { - let instance = ty::Instance::resolve( + let instance = ty::Instance::resolve_for_fn_ptr( bx.tcx(), ty::ParamEnv::reveal_all(), def_id, substs, ) - .unwrap() .unwrap(); InlineAsmOperandRef::SymFn { instance } } else { diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 925b8d329668f..3b05ffa567f86 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -633,14 +633,21 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { let ty = self.monomorphize(ty); visit_drop_use(self.tcx, ty, true, self.output); } + mir::TerminatorKind::InlineAsm { ref operands, .. } => { + for op in operands { + if let mir::InlineAsmOperand::SymFn { value } = op { + let fn_ty = self.monomorphize(value.literal.ty); + visit_fn_use(self.tcx, fn_ty, false, &mut self.output); + } + } + } mir::TerminatorKind::Goto { .. } | mir::TerminatorKind::SwitchInt { .. } | mir::TerminatorKind::Resume | mir::TerminatorKind::Abort | mir::TerminatorKind::Return | mir::TerminatorKind::Unreachable - | mir::TerminatorKind::Assert { .. } - | mir::TerminatorKind::InlineAsm { .. } => {} + | mir::TerminatorKind::Assert { .. } => {} mir::TerminatorKind::GeneratorDrop | mir::TerminatorKind::Yield { .. } | mir::TerminatorKind::FalseEdges { .. } diff --git a/src/test/ui/asm/sym.rs b/src/test/ui/asm/sym.rs new file mode 100644 index 0000000000000..83a3672af49ce --- /dev/null +++ b/src/test/ui/asm/sym.rs @@ -0,0 +1,38 @@ +// no-system-llvm +// only-x86_64 +// run-pass + +#![feature(asm, track_caller)] + +extern "C" fn f1() -> i32 { + 111 +} + +// The compiler will generate a shim to hide the caller location parameter. +#[track_caller] +fn f2() -> i32 { + 222 +} + +macro_rules! call { + ($func:path) => {{ + let result: i32; + unsafe { + asm!("call {}", sym $func, + out("rax") result, + out("rcx") _, out("rdx") _, out("rdi") _, out("rsi") _, + out("r8") _, out("r9") _, out("r10") _, out("r11") _, + out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _, + out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _, + out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _, + out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _, + ); + } + result + }} +} + +fn main() { + assert_eq!(call!(f1), 111); + assert_eq!(call!(f2), 222); +}