Skip to content

Commit

Permalink
Auto merge of #55179 - bjorn3:miri_public_op_field, r=RalfJung
Browse files Browse the repository at this point in the history
Give OpTy access to locals for priroda

r? @oli-obk
  • Loading branch information
bors committed Oct 21, 2018
2 parents 12a88a6 + b178553 commit 424a749
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 19 deletions.
12 changes: 4 additions & 8 deletions src/librustc_mir/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -733,4 +730,3 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
truncate(value, ty.size)
}
}

5 changes: 5 additions & 0 deletions src/librustc_mir/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 17 additions & 6 deletions src/librustc_mir/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)?;
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_mir/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
},
Expand All @@ -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) => {
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/interpret/terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<_>>()
);
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 424a749

Please sign in to comment.