about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAmanieu d'Antras <amanieu@gmail.com>2020-05-24 02:04:49 +0100
committerAmanieu d'Antras <amanieu@gmail.com>2020-05-24 02:04:49 +0100
commit3ed1e79cc40133b6cdb65955c7433cc483a89ca8 (patch)
tree26209bd7f48deaf082b0d1dcd25b8a43d7f095c6
parent215f2d3294b08dbdcf8f7d40de21ef1e7eae0a2d (diff)
downloadrust-3ed1e79cc40133b6cdb65955c7433cc483a89ca8.tar.gz
rust-3ed1e79cc40133b6cdb65955c7433cc483a89ca8.zip
Properly handle InlineAsmOperand::SymFn when collecting monomorphized items
Fixes #72484
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs3
-rw-r--r--src/librustc_mir/monomorphize/collector.rs11
-rw-r--r--src/test/ui/asm/sym.rs38
3 files changed, 48 insertions, 4 deletions
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index b487ed8dea8..2a6d1abba9e 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 925b8d32966..3b05ffa567f 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 00000000000..83a3672af49
--- /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);
+}