about summary refs log tree commit diff
diff options
context:
space:
mode:
authorhyd-dev <yd-huang@outlook.com>2021-05-21 22:19:37 +0800
committerhyd-dev <yd-huang@outlook.com>2021-05-21 22:24:57 +0800
commitc69fba929bba757a4ec97564cd4e78e988c11950 (patch)
tree88853a66e8253fb9af80ad91487d49bd179c9cba
parentf36b137074407ce857e34337bc92f10e26bc3994 (diff)
downloadrust-c69fba929bba757a4ec97564cd4e78e988c11950.tar.gz
rust-c69fba929bba757a4ec97564cd4e78e988c11950.zip
Add `rustc_mir::interpret::Machine::enforce_abi()`
-rw-r--r--compiler/rustc_mir/src/interpret/machine.rs8
-rw-r--r--compiler/rustc_mir/src/interpret/terminator.rs40
2 files changed, 29 insertions, 19 deletions
diff --git a/compiler/rustc_mir/src/interpret/machine.rs b/compiler/rustc_mir/src/interpret/machine.rs
index e7d7c38cc8f..3972c2f944b 100644
--- a/compiler/rustc_mir/src/interpret/machine.rs
+++ b/compiler/rustc_mir/src/interpret/machine.rs
@@ -132,6 +132,9 @@ 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;
+
     /// 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, ...
@@ -445,6 +448,11 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
     }
 
     #[inline(always)]
+    fn enforce_abi(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
+        true
+    }
+
+    #[inline(always)]
     fn call_extra_fn(
         _ecx: &mut InterpCx<$mir, $tcx, Self>,
         fn_val: !,
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(())
         };