about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2021-05-17 18:51:59 +0200
committerGitHub <noreply@github.com>2021-05-17 18:51:59 +0200
commitb93753ee219729a8a762b85fd34c8b8d9f3be6d0 (patch)
treebf476baa613bde695319e6486542efe4478197b5
parent9964284fed181676300aad693449f5b751e35ff2 (diff)
parent97bc0eefe7566955eedff5fb587807224b2387c3 (diff)
downloadrust-b93753ee219729a8a762b85fd34c8b8d9f3be6d0.tar.gz
rust-b93753ee219729a8a762b85fd34c8b8d9f3be6d0.zip
Rollup merge of #85087 - hyd-dev:lots-of-abis, r=RalfJung
`eval_fn_call`: check the ABI of `body.source`

And stop checking `instance_ty.fn_sig(*self.tcx).abi()`, if the function is not an intrinsic.
Addresses https://github.com/rust-lang/miri/pull/1776#discussion_r615381169.
No idea how to test this without Miri...
-rw-r--r--compiler/rustc_mir/src/interpret/terminator.rs29
1 files changed, 18 insertions, 11 deletions
diff --git a/compiler/rustc_mir/src/interpret/terminator.rs b/compiler/rustc_mir/src/interpret/terminator.rs
index 4aa1360d535..a7fcb41f74a 100644
--- a/compiler/rustc_mir/src/interpret/terminator.rs
+++ b/compiler/rustc_mir/src/interpret/terminator.rs
@@ -3,7 +3,10 @@ use std::convert::TryFrom;
 
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::Instance;
-use rustc_middle::{mir, ty};
+use rustc_middle::{
+    mir,
+    ty::{self, Ty},
+};
 use rustc_target::abi::{self, LayoutOf as _};
 use rustc_target::spec::abi::Abi;
 
@@ -228,15 +231,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         };
 
         // ABI check
-        {
-            let callee_abi = {
-                let instance_ty = instance.ty(*self.tcx, self.param_env);
-                match instance_ty.kind() {
-                    ty::FnDef(..) => instance_ty.fn_sig(*self.tcx).abi(),
-                    ty::Closure(..) => Abi::RustCall,
-                    ty::Generator(..) => Abi::Rust,
-                    _ => span_bug!(self.cur_span(), "unexpected callee ty: {:?}", instance_ty),
-                }
+        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 =>
@@ -253,10 +253,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     caller_abi.name()
                 )
             }
-        }
+            Ok(())
+        };
 
         match instance.def {
             ty::InstanceDef::Intrinsic(..) => {
+                check_abi(self, instance.ty(*self.tcx, self.param_env))?;
                 assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic);
                 M::call_intrinsic(self, instance, args, ret, unwind)
             }
@@ -274,6 +276,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         None => return Ok(()),
                     };
 
+                // Check against the ABI of the MIR body we are calling (not the ABI of `instance`;
+                // these can differ when `find_mir_or_eval_fn` does something clever like resolve
+                // exported symbol names).
+                check_abi(self, self.tcx.type_of(body.source.def_id()))?;
+
                 self.push_stack_frame(
                     instance,
                     body,