about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-05-22 11:49:13 +0000
committerbors <bors@rust-lang.org>2021-05-22 11:49:13 +0000
commit104a3c3510bad05bc58af8f3c7b8947d04a8a3dd (patch)
tree8916ed146899fd077c3f49bc34df07fd65514aa2
parent70cb58ce279444ac0191c4aa6df79becbaf2bdc1 (diff)
parent7e42c975b9fec39a385fb27e3f1610721a9d5e86 (diff)
downloadrust-104a3c3510bad05bc58af8f3c7b8947d04a8a3dd.tar.gz
rust-104a3c3510bad05bc58af8f3c7b8947d04a8a3dd.zip
Auto merge of #85557 - hyd-dev:abi, r=RalfJung
Add `rustc_mir::interpret::Machine::enforce_abi()`

To specify whether to skip the [ABI](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_target/abi/enum.Abi.html) check for function calls, so that we could test unwinding out of a `extern "C"` function call in Miri by disabling the check: https://github.com/rust-lang/miri/pull/1776#discussion_r633698382

I have tested that it works in Miri with a `-Zmiri-disable-abi-check` command line flag.
-rw-r--r--compiler/rustc_mir/src/interpret/machine.rs5
-rw-r--r--compiler/rustc_mir/src/interpret/terminator.rs40
2 files changed, 26 insertions, 19 deletions
diff --git a/compiler/rustc_mir/src/interpret/machine.rs b/compiler/rustc_mir/src/interpret/machine.rs
index e7d7c38cc8f..0ca99da7304 100644
--- a/compiler/rustc_mir/src/interpret/machine.rs
+++ b/compiler/rustc_mir/src/interpret/machine.rs
@@ -132,6 +132,11 @@ pub trait Machine<'mir, 'tcx>: Sized {
     /// Whether to enforce the validity invariant
     fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
 
+    /// Whether function calls should be [ABI](Abi)-checked.
+    fn enforce_abi(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
+        true
+    }
+
     /// Entry point for obtaining the MIR of anything that should get evaluated.
     /// So not just functions and shims, but also const/static initializers, anonymous
     /// constants, ...
diff --git a/compiler/rustc_mir/src/interpret/terminator.rs b/compiler/rustc_mir/src/interpret/terminator.rs
index a7fcb41f74a..a3dc8aaef32 100644
--- a/compiler/rustc_mir/src/interpret/terminator.rs
+++ b/compiler/rustc_mir/src/interpret/terminator.rs
@@ -232,26 +232,28 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
         // ABI check
         let check_abi = |this: &Self, instance_ty: Ty<'tcx>| -> InterpResult<'tcx> {
-            let callee_abi = match instance_ty.kind() {
-                ty::FnDef(..) => instance_ty.fn_sig(*this.tcx).abi(),
-                ty::Closure(..) => Abi::RustCall,
-                ty::Generator(..) => Abi::Rust,
-                _ => span_bug!(this.cur_span(), "unexpected callee ty: {:?}", instance_ty),
-            };
-            let normalize_abi = |abi| match abi {
-                Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic =>
-                // These are all the same ABI, really.
-                {
-                    Abi::Rust
+            if M::enforce_abi(this) {
+                let callee_abi = match instance_ty.kind() {
+                    ty::FnDef(..) => instance_ty.fn_sig(*this.tcx).abi(),
+                    ty::Closure(..) => Abi::RustCall,
+                    ty::Generator(..) => Abi::Rust,
+                    _ => span_bug!(this.cur_span(), "unexpected callee ty: {:?}", instance_ty),
+                };
+                let normalize_abi = |abi| match abi {
+                    Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic =>
+                    // These are all the same ABI, really.
+                    {
+                        Abi::Rust
+                    }
+                    abi => abi,
+                };
+                if normalize_abi(caller_abi) != normalize_abi(callee_abi) {
+                    throw_ub_format!(
+                        "calling a function with ABI {} using caller ABI {}",
+                        callee_abi.name(),
+                        caller_abi.name()
+                    )
                 }
-                abi => abi,
-            };
-            if normalize_abi(caller_abi) != normalize_abi(callee_abi) {
-                throw_ub_format!(
-                    "calling a function with ABI {} using caller ABI {}",
-                    callee_abi.name(),
-                    caller_abi.name()
-                )
             }
             Ok(())
         };