Skip to content

Commit 920dad9

Browse files
committed
[BROKEN] rustc_mir: use FnAbi to get abi::call::Conv in miri.
1 parent 0232114 commit 920dad9

File tree

3 files changed

+38
-31
lines changed

3 files changed

+38
-31
lines changed

src/librustc/mir/interpret/error.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::ty::query::TyCtxtAt;
1010
use backtrace::Backtrace;
1111
use errors::DiagnosticBuilder;
1212
use rustc_macros::HashStable;
13-
use rustc_target::spec::abi::Abi;
13+
use rustc_target::abi;
1414
use syntax_pos::{Pos, Span};
1515
use syntax::symbol::Symbol;
1616

@@ -396,7 +396,7 @@ pub enum UnsupportedOpInfo<'tcx> {
396396
Unsupported(String),
397397

398398
// -- Everything below is not categorized yet --
399-
FunctionAbiMismatch(Abi, Abi),
399+
FunctionAbiMismatch(abi::call::Conv, abi::call::Conv),
400400
FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>),
401401
FunctionRetMismatch(Ty<'tcx>, Ty<'tcx>),
402402
FunctionArgCountMismatch,
@@ -460,9 +460,9 @@ impl fmt::Debug for UnsupportedOpInfo<'tcx> {
460460
write!(f, "type validation failed: {}", err)
461461
}
462462
NoMirFor(ref func) => write!(f, "no MIR for `{}`", func),
463-
FunctionAbiMismatch(caller_abi, callee_abi) =>
463+
FunctionAbiMismatch(caller_conv, callee_conv) =>
464464
write!(f, "tried to call a function with ABI {:?} using caller ABI {:?}",
465-
callee_abi, caller_abi),
465+
callee_conv, caller_conv),
466466
FunctionArgMismatch(caller_ty, callee_ty) =>
467467
write!(f, "tried to call a function with argument of type {:?} \
468468
passing data of type {:?}",

src/librustc_mir/interpret/terminator.rs

+30-26
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::borrow::Cow;
22

3-
use rustc::{mir, ty};
4-
use rustc::ty::Instance;
5-
use rustc::ty::layout::{self, TyLayout, LayoutOf};
3+
use rustc::mir;
4+
use rustc::ty::{self, Instance, Ty};
5+
use rustc::ty::layout::{self, FnAbiExt, TyLayout, LayoutOf};
66
use syntax::source_map::Span;
7+
use rustc_target::abi::call::FnAbi;
78
use rustc_target::spec::abi::Abi;
89

910
use super::{
@@ -60,16 +61,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
6061
..
6162
} => {
6263
let func = self.eval_operand(func, None)?;
63-
let (fn_val, abi) = match func.layout.ty.kind {
64+
let (fn_val, abi, fn_abi) = match func.layout.ty.kind {
6465
ty::FnPtr(sig) => {
6566
let caller_abi = sig.abi();
6667
let fn_ptr = self.read_scalar(func)?.not_undef()?;
6768
let fn_val = self.memory.get_fn(fn_ptr)?;
68-
(fn_val, caller_abi)
69+
// FIXME(eddyb) compute `extra_args` to pass to
70+
// `FnAbi::of_fn_ptr` to support C variadics.
71+
(fn_val, caller_abi, FnAbi::of_fn_ptr(self, sig, &[]))
6972
}
7073
ty::FnDef(def_id, substs) => {
7174
let sig = func.layout.ty.fn_sig(*self.tcx);
72-
(FnVal::Instance(self.resolve(def_id, substs)?), sig.abi())
75+
let instance = self.resolve(def_id, substs)?;
76+
// FIXME(eddyb) compute `extra_args` to pass to
77+
// `FnAbi::of_instance` to support C variadics.
78+
let fn_abi = FnAbi::of_instance(self, instance, &[]);
79+
(FnVal::Instance(instance), sig.abi(), fn_abi)
7380
},
7481
_ => {
7582
bug!("invalid callee of type {:?}", func.layout.ty)
@@ -84,6 +91,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
8491
fn_val,
8592
terminator.source_info.span,
8693
abi,
94+
&fn_abi,
8795
&args[..],
8896
ret,
8997
*cleanup
@@ -234,7 +242,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
234242
&mut self,
235243
fn_val: FnVal<'tcx, M::ExtraFnVal>,
236244
span: Span,
245+
// FIXME(eddyb) this shouldn't be needed, its main purpose
246+
// right now is special-casing `RustCall` and intrinsics.
237247
caller_abi: Abi,
248+
caller_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
238249
args: &[OpTy<'tcx, M::PointerTag>],
239250
ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
240251
unwind: Option<mir::BasicBlock>
@@ -249,26 +260,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
249260
};
250261

251262
// ABI check
263+
// FIXME(eddyb) check every aspect of `FnAbi` and use it below
264+
// for adjusting various details (such as ignoring ZSTs).
252265
{
253-
let callee_abi = {
254-
let instance_ty = instance.ty(*self.tcx);
255-
match instance_ty.kind {
256-
ty::FnDef(..) =>
257-
instance_ty.fn_sig(*self.tcx).abi(),
258-
ty::Closure(..) => Abi::RustCall,
259-
ty::Generator(..) => Abi::Rust,
260-
_ => bug!("unexpected callee ty: {:?}", instance_ty),
261-
}
262-
};
263-
let normalize_abi = |abi| match abi {
264-
Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic =>
265-
// These are all the same ABI, really.
266-
Abi::Rust,
267-
abi =>
268-
abi,
269-
};
270-
if normalize_abi(caller_abi) != normalize_abi(callee_abi) {
271-
throw_unsup!(FunctionAbiMismatch(caller_abi, callee_abi))
266+
// FIXME(eddyb) compute `extra_args` to pass to
267+
// `FnAbi::of_instance` to support C variadics.
268+
let callee_fn_abi = FnAbi::of_instance(self, instance, &[]);
269+
if caller_fn_abi.conv != callee_fn_abi.conv {
270+
throw_unsup!(FunctionAbiMismatch(caller_fn_abi.conv, callee_fn_abi.conv))
272271
}
273272
}
274273

@@ -444,7 +443,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
444443
});
445444
trace!("Patched self operand to {:#?}", args[0]);
446445
// recurse with concrete function
447-
self.eval_fn_call(drop_fn, span, caller_abi, &args, ret, unwind)
446+
self.eval_fn_call(drop_fn, span, caller_abi, caller_fn_abi, &args, ret, unwind)
448447
}
449448
}
450449
}
@@ -479,10 +478,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
479478
let ty = self.tcx.mk_unit(); // return type is ()
480479
let dest = MPlaceTy::dangling(self.layout_of(ty)?, self);
481480

481+
// FIXME(eddyb) perhaps compute this more like the way it's done in
482+
// `rustc_codegen_ssa::mir::block`?
483+
let fn_abi = FnAbi::of_instance(self, instance, &[]);
484+
482485
self.eval_fn_call(
483486
FnVal::Instance(instance),
484487
span,
485488
Abi::Rust,
489+
&fn_abi,
486490
&[arg.into()],
487491
Some((dest.into(), target)),
488492
unwind

src/librustc_target/abi/call/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use crate::abi::{self, Abi, Align, FieldPlacement, Size};
22
use crate::abi::{HasDataLayout, LayoutOf, TyLayout, TyLayoutMethods};
33
use crate::spec::{self, HasTargetSpec};
44

5+
use rustc_macros::HashStable_Generic;
6+
57
mod aarch64;
68
mod amdgpu;
79
mod arm;
@@ -488,7 +490,8 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
488490
}
489491
}
490492

491-
#[derive(Copy, Clone, PartialEq, Debug)]
493+
#[derive(Copy, Clone, PartialEq, Debug, RustcEncodable, RustcDecodable)]
494+
#[derive(HashStable_Generic)]
492495
pub enum Conv {
493496
// General language calling conventions, for which every target
494497
// should have its own backend (e.g. LLVM) support.

0 commit comments

Comments
 (0)