mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 17:24:06 +00:00
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:
commit
424a749a01
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)?;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user