only count deref_operand as actual deref, but not all ref-to-place conversions
This commit is contained in:
parent
f174099885
commit
154835e5e7
@ -183,8 +183,7 @@ pub fn hook_fn(
|
||||
} else if Some(def_id) == self.tcx.lang_items().panic_fn() {
|
||||
assert!(args.len() == 1);
|
||||
// &(&'static str, &'static str, u32, u32)
|
||||
let ptr = self.read_immediate(args[0])?;
|
||||
let place = self.ref_to_mplace(ptr)?;
|
||||
let place = self.deref_operand(args[0])?;
|
||||
let (msg, file, line, col) = (
|
||||
self.mplace_field(place, 0)?,
|
||||
self.mplace_field(place, 1)?,
|
||||
@ -192,9 +191,9 @@ pub fn hook_fn(
|
||||
self.mplace_field(place, 3)?,
|
||||
);
|
||||
|
||||
let msg_place = self.ref_to_mplace(self.read_immediate(msg.into())?)?;
|
||||
let msg_place = self.deref_operand(msg.into())?;
|
||||
let msg = Symbol::intern(self.read_str(msg_place)?);
|
||||
let file_place = self.ref_to_mplace(self.read_immediate(file.into())?)?;
|
||||
let file_place = self.deref_operand(file.into())?;
|
||||
let file = Symbol::intern(self.read_str(file_place)?);
|
||||
let line = self.read_scalar(line.into())?.to_u32()?;
|
||||
let col = self.read_scalar(col.into())?.to_u32()?;
|
||||
@ -203,17 +202,16 @@ pub fn hook_fn(
|
||||
assert!(args.len() == 2);
|
||||
// &'static str, &(&'static str, u32, u32)
|
||||
let msg = args[0];
|
||||
let ptr = self.read_immediate(args[1])?;
|
||||
let place = self.ref_to_mplace(ptr)?;
|
||||
let place = self.deref_operand(args[1])?;
|
||||
let (file, line, col) = (
|
||||
self.mplace_field(place, 0)?,
|
||||
self.mplace_field(place, 1)?,
|
||||
self.mplace_field(place, 2)?,
|
||||
);
|
||||
|
||||
let msg_place = self.ref_to_mplace(self.read_immediate(msg.into())?)?;
|
||||
let msg_place = self.deref_operand(msg.into())?;
|
||||
let msg = Symbol::intern(self.read_str(msg_place)?);
|
||||
let file_place = self.ref_to_mplace(self.read_immediate(file.into())?)?;
|
||||
let file_place = self.deref_operand(file.into())?;
|
||||
let file = Symbol::intern(self.read_str(file_place)?);
|
||||
let line = self.read_scalar(line.into())?.to_u32()?;
|
||||
let col = self.read_scalar(col.into())?.to_u32()?;
|
||||
|
@ -555,17 +555,6 @@ pub fn operand_downcast(
|
||||
})
|
||||
}
|
||||
|
||||
// Take an operand, representing a pointer, and dereference it to a place -- that
|
||||
// will always be a MemPlace.
|
||||
pub(super) fn deref_operand(
|
||||
&self,
|
||||
src: OpTy<'tcx, M::PointerTag>,
|
||||
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||
let val = self.read_immediate(src)?;
|
||||
trace!("deref to {} on {:?}", val.layout.ty, *val);
|
||||
Ok(self.ref_to_mplace(val)?)
|
||||
}
|
||||
|
||||
pub fn operand_projection(
|
||||
&self,
|
||||
base: OpTy<'tcx, M::PointerTag>,
|
||||
|
@ -277,6 +277,8 @@ impl<'a, 'mir, 'tcx, Tag, M> EvalContext<'a, 'mir, 'tcx, M>
|
||||
{
|
||||
/// Take a value, which represents a (thin or fat) reference, and make it a place.
|
||||
/// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`.
|
||||
/// This does NOT call the "deref" machine hook, so it does NOT count as a
|
||||
/// deref as far as Stacked Borrows is concerned. Use `deref_operand` for that!
|
||||
pub fn ref_to_mplace(
|
||||
&self,
|
||||
val: ImmTy<'tcx, M::PointerTag>,
|
||||
@ -284,11 +286,25 @@ pub fn ref_to_mplace(
|
||||
let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
|
||||
let layout = self.layout_of(pointee_type)?;
|
||||
|
||||
let align = layout.align;
|
||||
let meta = val.to_meta()?;
|
||||
let ptr = val.to_scalar_ptr()?;
|
||||
let mplace = MemPlace { ptr, align, meta };
|
||||
let mut mplace = MPlaceTy { mplace, layout };
|
||||
let mplace = MemPlace {
|
||||
ptr: val.to_scalar_ptr()?,
|
||||
align: layout.align,
|
||||
meta: val.to_meta()?,
|
||||
};
|
||||
Ok(MPlaceTy { mplace, layout })
|
||||
}
|
||||
|
||||
// Take an operand, representing a pointer, and dereference it to a place -- that
|
||||
// will always be a MemPlace. Lives in `place.rs` because it creates a place.
|
||||
// This calls the "deref" machine hook, and counts as a deref as far as
|
||||
// Stacked Borrows is concerned.
|
||||
pub fn deref_operand(
|
||||
&self,
|
||||
src: OpTy<'tcx, M::PointerTag>,
|
||||
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||
let val = self.read_immediate(src)?;
|
||||
trace!("deref to {} on {:?}", val.layout.ty, *val);
|
||||
let mut place = self.ref_to_mplace(val)?;
|
||||
// Pointer tag tracking might want to adjust the tag.
|
||||
let mutbl = match val.layout.ty.sty {
|
||||
// `builtin_deref` considers boxes immutable, that's useless for our purposes
|
||||
@ -297,9 +313,8 @@ pub fn ref_to_mplace(
|
||||
ty::RawPtr(_) => None,
|
||||
_ => bug!("Unexpected pointer type {}", val.layout.ty.sty),
|
||||
};
|
||||
mplace.mplace.ptr = M::tag_dereference(self, mplace, mutbl)?;
|
||||
// Done
|
||||
Ok(mplace)
|
||||
place.mplace.ptr = M::tag_dereference(self, place, mutbl)?;
|
||||
Ok(place)
|
||||
}
|
||||
|
||||
/// Offset a pointer to project to a field. Unlike place_field, this is always
|
||||
|
@ -402,7 +402,7 @@ fn eval_fn_call(
|
||||
ty::InstanceDef::Virtual(_, idx) => {
|
||||
let ptr_size = self.pointer_size();
|
||||
let ptr_align = self.tcx.data_layout.pointer_align;
|
||||
let ptr = self.ref_to_mplace(self.read_immediate(args[0])?)?;
|
||||
let ptr = self.deref_operand(args[0])?;
|
||||
let vtable = ptr.vtable()?;
|
||||
let fn_ptr = self.memory.read_ptr_sized(
|
||||
vtable.offset(ptr_size * (idx as u64 + 3), self)?,
|
||||
|
@ -322,13 +322,10 @@ fn visit_primitive(&mut self, value: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'
|
||||
}
|
||||
}
|
||||
}
|
||||
// Turn ptr into place.
|
||||
// `ref_to_mplace` also calls the machine hook for (re)activating the tag,
|
||||
// which in turn will (in full miri) check if the pointer is dereferencable.
|
||||
let place = self.ecx.ref_to_mplace(value)?;
|
||||
// Recursive checking
|
||||
if let Some(ref mut ref_tracking) = self.ref_tracking {
|
||||
assert!(self.const_mode, "We should only do recursie checking in const mode");
|
||||
let place = self.ecx.ref_to_mplace(value)?;
|
||||
if size != Size::ZERO {
|
||||
// Non-ZST also have to be dereferencable
|
||||
let ptr = try_validation!(place.ptr.to_ptr(),
|
||||
|
Loading…
Reference in New Issue
Block a user