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:
@@ -324,14 +324,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
|||||||
|
|
||||||
pub fn layout_of_local(
|
pub fn layout_of_local(
|
||||||
&self,
|
&self,
|
||||||
frame: usize,
|
frame: &Frame<'mir, 'tcx, M::PointerTag>,
|
||||||
local: mir::Local
|
local: mir::Local
|
||||||
) -> EvalResult<'tcx, TyLayout<'tcx>> {
|
) -> EvalResult<'tcx, TyLayout<'tcx>> {
|
||||||
let local_ty = self.stack[frame].mir.local_decls[local].ty;
|
let local_ty = frame.mir.local_decls[local].ty;
|
||||||
let local_ty = self.monomorphize(
|
let local_ty = self.monomorphize(local_ty, frame.instance.substs);
|
||||||
local_ty,
|
|
||||||
self.stack[frame].instance.substs
|
|
||||||
);
|
|
||||||
self.layout_of(local_ty)
|
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");
|
assert!(local != mir::RETURN_PLACE, "Cannot make return place live");
|
||||||
trace!("{:?} is now live", local);
|
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)?);
|
let init = LocalValue::Live(self.uninit_operand(layout)?);
|
||||||
// StorageLive *always* kills the value that's currently stored
|
// StorageLive *always* kills the value that's currently stored
|
||||||
Ok(mem::replace(&mut self.frame_mut().locals[local], init))
|
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)
|
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);
|
self.dump_allocs(leaks);
|
||||||
n
|
n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This is used by [priroda](https://github.com/oli-obk/priroda)
|
||||||
|
pub fn alloc_map(&self) -> &M::MemoryMap {
|
||||||
|
&self.alloc_map
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Byte accessors
|
/// 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
|
// 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
|
// avoid allocations. If you already know the layout, you can pass it in
|
||||||
// to avoid looking it up again.
|
// 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::*;
|
use rustc::mir::Place::*;
|
||||||
let op = match *mir_place {
|
let op = match *mir_place {
|
||||||
Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer),
|
Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer),
|
||||||
Local(local) => {
|
Local(local) => self.access_local(self.frame(), local, layout)?,
|
||||||
let op = *self.frame().locals[local].access()?;
|
|
||||||
let layout = from_known_layout(layout,
|
|
||||||
|| self.layout_of_local(self.cur_frame(), local))?;
|
|
||||||
OpTy { op, layout }
|
|
||||||
},
|
|
||||||
|
|
||||||
Projection(ref proj) => {
|
Projection(ref proj) => {
|
||||||
let op = self.eval_place_to_op(&proj.base, None)?;
|
let op = self.eval_place_to_op(&proj.base, None)?;
|
||||||
|
|||||||
@@ -588,7 +588,7 @@ where
|
|||||||
// their layout on return.
|
// their layout on return.
|
||||||
PlaceTy {
|
PlaceTy {
|
||||||
place: *return_place,
|
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),
|
None => return err!(InvalidNullPointerUsage),
|
||||||
},
|
},
|
||||||
@@ -597,7 +597,7 @@ where
|
|||||||
frame: self.cur_frame(),
|
frame: self.cur_frame(),
|
||||||
local,
|
local,
|
||||||
},
|
},
|
||||||
layout: self.layout_of_local(self.cur_frame(), local)?,
|
layout: self.layout_of_local(self.frame(), local)?,
|
||||||
},
|
},
|
||||||
|
|
||||||
Projection(ref proj) => {
|
Projection(ref proj) => {
|
||||||
@@ -856,7 +856,7 @@ where
|
|||||||
// We need the layout of the local. We can NOT use the layout we got,
|
// 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 might e.g. be an inner field of a struct with `Scalar` layout,
|
||||||
// that has different alignment than the outer field.
|
// 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)?;
|
let ptr = self.allocate(local_layout, MemoryKind::Stack)?;
|
||||||
// We don't have to validate as we can assume the local
|
// We don't have to validate as we can assume the local
|
||||||
// was already valid for its type.
|
// 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.spread_arg,
|
||||||
mir.args_iter()
|
mir.args_iter()
|
||||||
.map(|local|
|
.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<_>>()
|
.collect::<Vec<_>>()
|
||||||
);
|
);
|
||||||
@@ -380,7 +380,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let callee_layout =
|
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() {
|
if !callee_layout.abi.is_uninhabited() {
|
||||||
return err!(FunctionRetMismatch(
|
return err!(FunctionRetMismatch(
|
||||||
self.tcx.types.never, callee_layout.ty
|
self.tcx.types.never, callee_layout.ty
|
||||||
|
|||||||
Reference in New Issue
Block a user