Auto merge of #55179 - bjorn3:miri_public_op_field, r=RalfJung

Give OpTy access to locals for priroda

r? @oli-obk
This commit is contained in:
bors 2018-10-21 20:07:34 +00:00
commit 424a749a01
5 changed files with 31 additions and 19 deletions

View File

@ -324,14 +324,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
pub fn layout_of_local(
&self,
frame: usize,
frame: &Frame<'mir, 'tcx, M::PointerTag>,
local: mir::Local
) -> EvalResult<'tcx, TyLayout<'tcx>> {
let local_ty = self.stack[frame].mir.local_decls[local].ty;
let local_ty = self.monomorphize(
local_ty,
self.stack[frame].instance.substs
);
let local_ty = frame.mir.local_decls[local].ty;
let local_ty = self.monomorphize(local_ty, frame.instance.substs);
self.layout_of(local_ty)
}
@ -579,7 +576,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
assert!(local != mir::RETURN_PLACE, "Cannot make return place live");
trace!("{:?} is now live", local);
let layout = self.layout_of_local(self.cur_frame(), local)?;
let layout = self.layout_of_local(self.frame(), local)?;
let init = LocalValue::Live(self.uninit_operand(layout)?);
// StorageLive *always* kills the value that's currently stored
Ok(mem::replace(&mut self.frame_mut().locals[local], init))
@ -733,4 +730,3 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
truncate(value, ty.size)
}
}

View File

@ -603,6 +603,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
self.dump_allocs(leaks);
n
}
/// This is used by [priroda](https://github.com/oli-obk/priroda)
pub fn alloc_map(&self) -> &M::MemoryMap {
&self.alloc_map
}
}
/// Byte accessors

View File

@ -571,6 +571,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
})
}
/// This is used by [priroda](https://github.com/oli-obk/priroda) to get an OpTy from a local
///
/// When you know the layout of the local in advance, you can pass it as last argument
pub fn access_local(
&self,
frame: &super::Frame<'mir, 'tcx, M::PointerTag>,
local: mir::Local,
layout: Option<TyLayout<'tcx>>,
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
assert_ne!(local, mir::RETURN_PLACE);
let op = *frame.locals[local].access()?;
let layout = from_known_layout(layout,
|| self.layout_of_local(frame, local))?;
Ok(OpTy { op, layout })
}
// Evaluate a place with the goal of reading from it. This lets us sometimes
// avoid allocations. If you already know the layout, you can pass it in
// to avoid looking it up again.
@ -582,12 +598,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
use rustc::mir::Place::*;
let op = match *mir_place {
Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer),
Local(local) => {
let op = *self.frame().locals[local].access()?;
let layout = from_known_layout(layout,
|| self.layout_of_local(self.cur_frame(), local))?;
OpTy { op, layout }
},
Local(local) => self.access_local(self.frame(), local, layout)?,
Projection(ref proj) => {
let op = self.eval_place_to_op(&proj.base, None)?;

View File

@ -588,7 +588,7 @@ where
// their layout on return.
PlaceTy {
place: *return_place,
layout: self.layout_of_local(self.cur_frame(), mir::RETURN_PLACE)?,
layout: self.layout_of_local(self.frame(), mir::RETURN_PLACE)?,
},
None => return err!(InvalidNullPointerUsage),
},
@ -597,7 +597,7 @@ where
frame: self.cur_frame(),
local,
},
layout: self.layout_of_local(self.cur_frame(), local)?,
layout: self.layout_of_local(self.frame(), local)?,
},
Projection(ref proj) => {
@ -856,7 +856,7 @@ where
// We need the layout of the local. We can NOT use the layout we got,
// that might e.g. be an inner field of a struct with `Scalar` layout,
// that has different alignment than the outer field.
let local_layout = self.layout_of_local(frame, local)?;
let local_layout = self.layout_of_local(&self.stack[frame], local)?;
let ptr = self.allocate(local_layout, MemoryKind::Stack)?;
// We don't have to validate as we can assume the local
// was already valid for its type.

View File

@ -310,7 +310,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
mir.spread_arg,
mir.args_iter()
.map(|local|
(local, self.layout_of_local(self.cur_frame(), local).unwrap().ty)
(local, self.layout_of_local(self.frame(), local).unwrap().ty)
)
.collect::<Vec<_>>()
);
@ -380,7 +380,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
}
} else {
let callee_layout =
self.layout_of_local(self.cur_frame(), mir::RETURN_PLACE)?;
self.layout_of_local(self.frame(), mir::RETURN_PLACE)?;
if !callee_layout.abi.is_uninhabited() {
return err!(FunctionRetMismatch(
self.tcx.types.never, callee_layout.ty