Skip to content

Commit 32453ce

Browse files
committed
remvoe to_scalar_ptr and use ref_to_mplace everywhere
1 parent 14ee66a commit 32453ce

File tree

4 files changed

+30
-62
lines changed

4 files changed

+30
-62
lines changed

src/librustc_mir/interpret/intern.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -192,20 +192,18 @@ for
192192
let ty = mplace.layout.ty;
193193
if let ty::Ref(_, referenced_ty, mutability) = ty.kind {
194194
let value = self.ecx.read_immediate(mplace.into())?;
195+
let mplace = self.ecx.ref_to_mplace(value)?;
195196
// Handle trait object vtables
196-
if let Ok(meta) = value.to_meta() {
197-
if let ty::Dynamic(..) =
198-
self.ecx.tcx.struct_tail_erasing_lifetimes(
199-
referenced_ty, self.ecx.param_env).kind
200-
{
201-
if let Ok(vtable) = meta.unwrap().to_ptr() {
202-
// explitly choose `Immutable` here, since vtables are immutable, even
203-
// if the reference of the fat pointer is mutable
204-
self.intern_shallow(vtable.alloc_id, Mutability::Immutable, None)?;
205-
}
197+
if let ty::Dynamic(..) =
198+
self.ecx.tcx.struct_tail_erasing_lifetimes(
199+
referenced_ty, self.ecx.param_env).kind
200+
{
201+
if let Ok(vtable) = mplace.meta.unwrap().to_ptr() {
202+
// explitly choose `Immutable` here, since vtables are immutable, even
203+
// if the reference of the fat pointer is mutable
204+
self.intern_shallow(vtable.alloc_id, Mutability::Immutable, None)?;
206205
}
207206
}
208-
let mplace = self.ecx.ref_to_mplace(value)?;
209207
// Check if we have encountered this pointer+layout combination before.
210208
// Only recurse for allocation-backed pointers.
211209
if let Scalar::Ptr(ptr) = mplace.ptr {
@@ -230,7 +228,7 @@ for
230228
ty::Array(_, n)
231229
if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {}
232230
ty::Slice(_)
233-
if value.to_meta().unwrap().unwrap().to_usize(self.ecx)? == 0 => {}
231+
if mplace.meta.unwrap().to_usize(self.ecx)? == 0 => {}
234232
_ => bug!("const qualif failed to prevent mutable references"),
235233
}
236234
},

src/librustc_mir/interpret/operand.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -82,26 +82,6 @@ impl<'tcx, Tag> Immediate<Tag> {
8282
Immediate::ScalarPair(a, b) => Ok((a.not_undef()?, b.not_undef()?))
8383
}
8484
}
85-
86-
/// Converts the immediate into a pointer (or a pointer-sized integer).
87-
/// Throws away the second half of a ScalarPair!
88-
#[inline]
89-
pub fn to_scalar_ptr(self) -> InterpResult<'tcx, Scalar<Tag>> {
90-
match self {
91-
Immediate::Scalar(ptr) |
92-
Immediate::ScalarPair(ptr, _) => ptr.not_undef(),
93-
}
94-
}
95-
96-
/// Converts the value into its metadata.
97-
/// Throws away the first half of a ScalarPair!
98-
#[inline]
99-
pub fn to_meta(self) -> InterpResult<'tcx, Option<Scalar<Tag>>> {
100-
Ok(match self {
101-
Immediate::Scalar(_) => None,
102-
Immediate::ScalarPair(_, meta) => Some(meta.not_undef()?),
103-
})
104-
}
10585
}
10686

10787
// ScalarPair needs a type to interpret, so we often have an immediate and a type together

src/librustc_mir/interpret/place.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,15 +291,19 @@ where
291291
.expect("`ref_to_mplace` called on non-ptr type")
292292
.ty;
293293
let layout = self.layout_of(pointee_type)?;
294+
let (ptr, meta) = match *val {
295+
Immediate::Scalar(ptr) => (ptr.not_undef()?, None),
296+
Immediate::ScalarPair(ptr, meta) => (ptr.not_undef()?, Some(meta.not_undef()?)),
297+
};
294298

295299
let mplace = MemPlace {
296-
ptr: val.to_scalar_ptr()?,
300+
ptr,
297301
// We could use the run-time alignment here. For now, we do not, because
298302
// the point of tracking the alignment here is to make sure that the *static*
299303
// alignment information emitted with the loads is correct. The run-time
300304
// alignment can only be more restrictive.
301305
align: layout.align.abi,
302-
meta: val.to_meta()?,
306+
meta,
303307
};
304308
Ok(MPlaceTy { mplace, layout })
305309
}

src/librustc_mir/interpret/validity.rs

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -388,44 +388,31 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
388388
}
389389
}
390390
ty::RawPtr(..) => {
391-
// Check pointer part.
392-
if self.ref_tracking_for_consts.is_some() {
393-
// Integers/floats in CTFE: For consistency with integers, we do not
394-
// accept undef.
395-
let _ptr = try_validation!(value.to_scalar_ptr(),
396-
"undefined address in raw pointer", self.path);
397-
} else {
398-
// Remain consistent with `usize`: Accept anything.
399-
}
400-
401-
// Check metadata.
402-
let meta = try_validation!(value.to_meta(),
403-
"uninitialized data in wide pointer metadata", self.path);
404-
let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
405-
if layout.is_unsized() {
406-
self.check_wide_ptr_meta(meta, layout)?;
391+
// We are conservative with undef for integers, but try to
392+
// actually enforce our current rules for raw pointers.
393+
let place = try_validation!(self.ecx.ref_to_mplace(value),
394+
"undefined pointer", self.path);
395+
if place.layout.is_unsized() {
396+
self.check_wide_ptr_meta(place.meta, place.layout)?;
407397
}
408398
}
409399
_ if ty.is_box() || ty.is_region_ptr() => {
410400
// Handle wide pointers.
411401
// Check metadata early, for better diagnostics
412-
let ptr = try_validation!(value.to_scalar_ptr(),
413-
"undefined address in pointer", self.path);
414-
let meta = try_validation!(value.to_meta(),
415-
"uninitialized data in wide pointer metadata", self.path);
416-
let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
417-
if layout.is_unsized() {
418-
self.check_wide_ptr_meta(meta, layout)?;
402+
let place = try_validation!(self.ecx.ref_to_mplace(value),
403+
"undefined pointer", self.path);
404+
if place.layout.is_unsized() {
405+
self.check_wide_ptr_meta(place.meta, place.layout)?;
419406
}
420407
// Make sure this is dereferencable and all.
421-
let (size, align) = self.ecx.size_and_align_of(meta, layout)?
408+
let (size, align) = self.ecx.size_and_align_of(place.meta, place.layout)?
422409
// for the purpose of validity, consider foreign types to have
423410
// alignment and size determined by the layout (size will be 0,
424411
// alignment should take attributes into account).
425-
.unwrap_or_else(|| (layout.size, layout.align.abi));
412+
.unwrap_or_else(|| (place.layout.size, place.layout.align.abi));
426413
let ptr: Option<_> = match
427414
self.ecx.memory.check_ptr_access_align(
428-
ptr,
415+
place.ptr,
429416
size,
430417
Some(align),
431418
CheckInAllocMsg::InboundsTest,
@@ -435,7 +422,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
435422
Err(err) => {
436423
info!(
437424
"{:?} did not pass access check for size {:?}, align {:?}",
438-
ptr, size, align
425+
place.ptr, size, align
439426
);
440427
match err.kind {
441428
err_unsup!(InvalidNullPointerUsage) =>
@@ -459,7 +446,6 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
459446
};
460447
// Recursive checking
461448
if let Some(ref mut ref_tracking) = self.ref_tracking_for_consts {
462-
let place = self.ecx.ref_to_mplace(value)?;
463449
if let Some(ptr) = ptr { // not a ZST
464450
// Skip validation entirely for some external statics
465451
let alloc_kind = self.ecx.tcx.alloc_map.lock().get(ptr.alloc_id);

0 commit comments

Comments
 (0)