Skip to content

Commit 154835e

Browse files
committed
only count deref_operand as actual deref, but not all ref-to-place conversions
1 parent f174099 commit 154835e

File tree

5 files changed

+31
-32
lines changed

5 files changed

+31
-32
lines changed

src/librustc_mir/interpret/intrinsics.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,18 +183,17 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
183183
} else if Some(def_id) == self.tcx.lang_items().panic_fn() {
184184
assert!(args.len() == 1);
185185
// &(&'static str, &'static str, u32, u32)
186-
let ptr = self.read_immediate(args[0])?;
187-
let place = self.ref_to_mplace(ptr)?;
186+
let place = self.deref_operand(args[0])?;
188187
let (msg, file, line, col) = (
189188
self.mplace_field(place, 0)?,
190189
self.mplace_field(place, 1)?,
191190
self.mplace_field(place, 2)?,
192191
self.mplace_field(place, 3)?,
193192
);
194193

195-
let msg_place = self.ref_to_mplace(self.read_immediate(msg.into())?)?;
194+
let msg_place = self.deref_operand(msg.into())?;
196195
let msg = Symbol::intern(self.read_str(msg_place)?);
197-
let file_place = self.ref_to_mplace(self.read_immediate(file.into())?)?;
196+
let file_place = self.deref_operand(file.into())?;
198197
let file = Symbol::intern(self.read_str(file_place)?);
199198
let line = self.read_scalar(line.into())?.to_u32()?;
200199
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>
203202
assert!(args.len() == 2);
204203
// &'static str, &(&'static str, u32, u32)
205204
let msg = args[0];
206-
let ptr = self.read_immediate(args[1])?;
207-
let place = self.ref_to_mplace(ptr)?;
205+
let place = self.deref_operand(args[1])?;
208206
let (file, line, col) = (
209207
self.mplace_field(place, 0)?,
210208
self.mplace_field(place, 1)?,
211209
self.mplace_field(place, 2)?,
212210
);
213211

214-
let msg_place = self.ref_to_mplace(self.read_immediate(msg.into())?)?;
212+
let msg_place = self.deref_operand(msg.into())?;
215213
let msg = Symbol::intern(self.read_str(msg_place)?);
216-
let file_place = self.ref_to_mplace(self.read_immediate(file.into())?)?;
214+
let file_place = self.deref_operand(file.into())?;
217215
let file = Symbol::intern(self.read_str(file_place)?);
218216
let line = self.read_scalar(line.into())?.to_u32()?;
219217
let col = self.read_scalar(col.into())?.to_u32()?;

src/librustc_mir/interpret/operand.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -555,17 +555,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
555555
})
556556
}
557557

558-
// Take an operand, representing a pointer, and dereference it to a place -- that
559-
// will always be a MemPlace.
560-
pub(super) fn deref_operand(
561-
&self,
562-
src: OpTy<'tcx, M::PointerTag>,
563-
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
564-
let val = self.read_immediate(src)?;
565-
trace!("deref to {} on {:?}", val.layout.ty, *val);
566-
Ok(self.ref_to_mplace(val)?)
567-
}
568-
569558
pub fn operand_projection(
570559
&self,
571560
base: OpTy<'tcx, M::PointerTag>,

src/librustc_mir/interpret/place.rs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -277,18 +277,34 @@ where
277277
{
278278
/// Take a value, which represents a (thin or fat) reference, and make it a place.
279279
/// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`.
280+
/// This does NOT call the "deref" machine hook, so it does NOT count as a
281+
/// deref as far as Stacked Borrows is concerned. Use `deref_operand` for that!
280282
pub fn ref_to_mplace(
281283
&self,
282284
val: ImmTy<'tcx, M::PointerTag>,
283285
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
284286
let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
285287
let layout = self.layout_of(pointee_type)?;
286288

287-
let align = layout.align;
288-
let meta = val.to_meta()?;
289-
let ptr = val.to_scalar_ptr()?;
290-
let mplace = MemPlace { ptr, align, meta };
291-
let mut mplace = MPlaceTy { mplace, layout };
289+
let mplace = MemPlace {
290+
ptr: val.to_scalar_ptr()?,
291+
align: layout.align,
292+
meta: val.to_meta()?,
293+
};
294+
Ok(MPlaceTy { mplace, layout })
295+
}
296+
297+
// Take an operand, representing a pointer, and dereference it to a place -- that
298+
// will always be a MemPlace. Lives in `place.rs` because it creates a place.
299+
// This calls the "deref" machine hook, and counts as a deref as far as
300+
// Stacked Borrows is concerned.
301+
pub fn deref_operand(
302+
&self,
303+
src: OpTy<'tcx, M::PointerTag>,
304+
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
305+
let val = self.read_immediate(src)?;
306+
trace!("deref to {} on {:?}", val.layout.ty, *val);
307+
let mut place = self.ref_to_mplace(val)?;
292308
// Pointer tag tracking might want to adjust the tag.
293309
let mutbl = match val.layout.ty.sty {
294310
// `builtin_deref` considers boxes immutable, that's useless for our purposes
@@ -297,9 +313,8 @@ where
297313
ty::RawPtr(_) => None,
298314
_ => bug!("Unexpected pointer type {}", val.layout.ty.sty),
299315
};
300-
mplace.mplace.ptr = M::tag_dereference(self, mplace, mutbl)?;
301-
// Done
302-
Ok(mplace)
316+
place.mplace.ptr = M::tag_dereference(self, place, mutbl)?;
317+
Ok(place)
303318
}
304319

305320
/// Offset a pointer to project to a field. Unlike place_field, this is always

src/librustc_mir/interpret/terminator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
402402
ty::InstanceDef::Virtual(_, idx) => {
403403
let ptr_size = self.pointer_size();
404404
let ptr_align = self.tcx.data_layout.pointer_align;
405-
let ptr = self.ref_to_mplace(self.read_immediate(args[0])?)?;
405+
let ptr = self.deref_operand(args[0])?;
406406
let vtable = ptr.vtable()?;
407407
let fn_ptr = self.memory.read_ptr_sized(
408408
vtable.offset(ptr_size * (idx as u64 + 3), self)?,

src/librustc_mir/interpret/validity.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,13 +322,10 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
322322
}
323323
}
324324
}
325-
// Turn ptr into place.
326-
// `ref_to_mplace` also calls the machine hook for (re)activating the tag,
327-
// which in turn will (in full miri) check if the pointer is dereferencable.
328-
let place = self.ecx.ref_to_mplace(value)?;
329325
// Recursive checking
330326
if let Some(ref mut ref_tracking) = self.ref_tracking {
331327
assert!(self.const_mode, "We should only do recursie checking in const mode");
328+
let place = self.ecx.ref_to_mplace(value)?;
332329
if size != Size::ZERO {
333330
// Non-ZST also have to be dereferencable
334331
let ptr = try_validation!(place.ptr.to_ptr(),

0 commit comments

Comments
 (0)