Properly handle InlineAsmOperand::SymFn when collecting monomorphized items

Fixes #72484
This commit is contained in:
Amanieu d'Antras 2020-05-24 02:04:49 +01:00
parent 215f2d3294
commit 3ed1e79cc4
3 changed files with 48 additions and 4 deletions

View File

@ -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 {

View File

@ -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 { .. }

38
src/test/ui/asm/sym.rs Normal file
View File

@ -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);
}