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 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
|||||||
} else if Some(def_id) == self.tcx.lang_items().panic_fn() {
|
} else if Some(def_id) == self.tcx.lang_items().panic_fn() {
|
||||||
assert!(args.len() == 1);
|
assert!(args.len() == 1);
|
||||||
// &(&'static str, &'static str, u32, u32)
|
// &(&'static str, &'static str, u32, u32)
|
||||||
let ptr = self.read_immediate(args[0])?;
|
let place = self.deref_operand(args[0])?;
|
||||||
let place = self.ref_to_mplace(ptr)?;
|
|
||||||
let (msg, file, line, col) = (
|
let (msg, file, line, col) = (
|
||||||
self.mplace_field(place, 0)?,
|
self.mplace_field(place, 0)?,
|
||||||
self.mplace_field(place, 1)?,
|
self.mplace_field(place, 1)?,
|
||||||
@ -192,9 +191,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
|||||||
self.mplace_field(place, 3)?,
|
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 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 file = Symbol::intern(self.read_str(file_place)?);
|
||||||
let line = self.read_scalar(line.into())?.to_u32()?;
|
let line = self.read_scalar(line.into())?.to_u32()?;
|
||||||
let col = self.read_scalar(col.into())?.to_u32()?;
|
let col = self.read_scalar(col.into())?.to_u32()?;
|
||||||
@ -203,17 +202,16 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
|||||||
assert!(args.len() == 2);
|
assert!(args.len() == 2);
|
||||||
// &'static str, &(&'static str, u32, u32)
|
// &'static str, &(&'static str, u32, u32)
|
||||||
let msg = args[0];
|
let msg = args[0];
|
||||||
let ptr = self.read_immediate(args[1])?;
|
let place = self.deref_operand(args[1])?;
|
||||||
let place = self.ref_to_mplace(ptr)?;
|
|
||||||
let (file, line, col) = (
|
let (file, line, col) = (
|
||||||
self.mplace_field(place, 0)?,
|
self.mplace_field(place, 0)?,
|
||||||
self.mplace_field(place, 1)?,
|
self.mplace_field(place, 1)?,
|
||||||
self.mplace_field(place, 2)?,
|
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 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 file = Symbol::intern(self.read_str(file_place)?);
|
||||||
let line = self.read_scalar(line.into())?.to_u32()?;
|
let line = self.read_scalar(line.into())?.to_u32()?;
|
||||||
let col = self.read_scalar(col.into())?.to_u32()?;
|
let col = self.read_scalar(col.into())?.to_u32()?;
|
||||||
|
@ -555,17 +555,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(
|
pub fn operand_projection(
|
||||||
&self,
|
&self,
|
||||||
base: OpTy<'tcx, M::PointerTag>,
|
base: OpTy<'tcx, M::PointerTag>,
|
||||||
|
@ -277,6 +277,8 @@ where
|
|||||||
{
|
{
|
||||||
/// Take a value, which represents a (thin or fat) reference, and make it a place.
|
/// 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()`.
|
/// 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(
|
pub fn ref_to_mplace(
|
||||||
&self,
|
&self,
|
||||||
val: ImmTy<'tcx, M::PointerTag>,
|
val: ImmTy<'tcx, M::PointerTag>,
|
||||||
@ -284,11 +286,25 @@ where
|
|||||||
let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
|
let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
|
||||||
let layout = self.layout_of(pointee_type)?;
|
let layout = self.layout_of(pointee_type)?;
|
||||||
|
|
||||||
let align = layout.align;
|
let mplace = MemPlace {
|
||||||
let meta = val.to_meta()?;
|
ptr: val.to_scalar_ptr()?,
|
||||||
let ptr = val.to_scalar_ptr()?;
|
align: layout.align,
|
||||||
let mplace = MemPlace { ptr, align, meta };
|
meta: val.to_meta()?,
|
||||||
let mut mplace = MPlaceTy { mplace, layout };
|
};
|
||||||
|
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.
|
// Pointer tag tracking might want to adjust the tag.
|
||||||
let mutbl = match val.layout.ty.sty {
|
let mutbl = match val.layout.ty.sty {
|
||||||
// `builtin_deref` considers boxes immutable, that's useless for our purposes
|
// `builtin_deref` considers boxes immutable, that's useless for our purposes
|
||||||
@ -297,9 +313,8 @@ where
|
|||||||
ty::RawPtr(_) => None,
|
ty::RawPtr(_) => None,
|
||||||
_ => bug!("Unexpected pointer type {}", val.layout.ty.sty),
|
_ => bug!("Unexpected pointer type {}", val.layout.ty.sty),
|
||||||
};
|
};
|
||||||
mplace.mplace.ptr = M::tag_dereference(self, mplace, mutbl)?;
|
place.mplace.ptr = M::tag_dereference(self, place, mutbl)?;
|
||||||
// Done
|
Ok(place)
|
||||||
Ok(mplace)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Offset a pointer to project to a field. Unlike place_field, this is always
|
/// Offset a pointer to project to a field. Unlike place_field, this is always
|
||||||
|
@ -402,7 +402,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
|||||||
ty::InstanceDef::Virtual(_, idx) => {
|
ty::InstanceDef::Virtual(_, idx) => {
|
||||||
let ptr_size = self.pointer_size();
|
let ptr_size = self.pointer_size();
|
||||||
let ptr_align = self.tcx.data_layout.pointer_align;
|
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 vtable = ptr.vtable()?;
|
||||||
let fn_ptr = self.memory.read_ptr_sized(
|
let fn_ptr = self.memory.read_ptr_sized(
|
||||||
vtable.offset(ptr_size * (idx as u64 + 3), self)?,
|
vtable.offset(ptr_size * (idx as u64 + 3), self)?,
|
||||||
|
@ -322,13 +322,10 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 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
|
// Recursive checking
|
||||||
if let Some(ref mut ref_tracking) = self.ref_tracking {
|
if let Some(ref mut ref_tracking) = self.ref_tracking {
|
||||||
assert!(self.const_mode, "We should only do recursie checking in const mode");
|
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 {
|
if size != Size::ZERO {
|
||||||
// Non-ZST also have to be dereferencable
|
// Non-ZST also have to be dereferencable
|
||||||
let ptr = try_validation!(place.ptr.to_ptr(),
|
let ptr = try_validation!(place.ptr.to_ptr(),
|
||||||
|
Loading…
Reference in New Issue
Block a user