Skip to content

Commit 54ab357

Browse files
committed
ptr_get_alloc_id: don't return an actual Pointer
1 parent ad4e98e commit 54ab357

File tree

2 files changed

+29
-30
lines changed

2 files changed

+29
-30
lines changed

compiler/rustc_const_eval/src/interpret/memory.rs

+28-29
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
238238
new_align: Align,
239239
kind: MemoryKind<M::MemoryKind>,
240240
) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
241-
let (alloc_id, offset, ptr) = self.ptr_get_alloc_id(ptr)?;
241+
let (alloc_id, offset, _tag) = self.ptr_get_alloc_id(ptr)?;
242242
if offset.bytes() != 0 {
243243
throw_ub_format!(
244244
"reallocating {:?} which does not point to the beginning of an object",
@@ -255,14 +255,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
255255
};
256256
// This will also call the access hooks.
257257
self.mem_copy(
258-
ptr.into(),
258+
ptr,
259259
Align::ONE,
260260
new_ptr.into(),
261261
Align::ONE,
262262
old_size.min(new_size),
263263
/*nonoverlapping*/ true,
264264
)?;
265-
self.deallocate_ptr(ptr.into(), old_size_and_align, kind)?;
265+
self.deallocate_ptr(ptr, old_size_and_align, kind)?;
266266

267267
Ok(new_ptr)
268268
}
@@ -274,7 +274,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
274274
old_size_and_align: Option<(Size, Align)>,
275275
kind: MemoryKind<M::MemoryKind>,
276276
) -> InterpResult<'tcx> {
277-
let (alloc_id, offset, ptr) = self.ptr_get_alloc_id(ptr)?;
277+
let (alloc_id, offset, tag) = self.ptr_get_alloc_id(ptr)?;
278278
trace!("deallocating: {}", alloc_id);
279279

280280
if offset.bytes() != 0 {
@@ -330,7 +330,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
330330
*self.tcx,
331331
&mut self.machine,
332332
&mut alloc.extra,
333-
ptr.provenance,
333+
tag,
334334
alloc_range(Size::ZERO, size),
335335
)?;
336336

@@ -350,17 +350,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
350350
ptr: Pointer<Option<M::PointerTag>>,
351351
size: Size,
352352
align: Align,
353-
) -> InterpResult<'tcx, Option<(AllocId, Size, Pointer<M::PointerTag>)>> {
353+
) -> InterpResult<'tcx, Option<(AllocId, Size, M::PointerTag)>> {
354354
let align = M::enforce_alignment(&self).then_some(align);
355355
self.check_and_deref_ptr(
356356
ptr,
357357
size,
358358
align,
359359
CheckInAllocMsg::MemoryAccessTest,
360-
|alloc_id, offset, ptr| {
360+
|alloc_id, offset, tag| {
361361
let (size, align) =
362362
self.get_alloc_size_and_align(alloc_id, AllocCheck::Dereferenceable)?;
363-
Ok((size, align, (alloc_id, offset, ptr)))
363+
Ok((size, align, (alloc_id, offset, tag)))
364364
},
365365
)
366366
}
@@ -404,7 +404,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
404404
alloc_size: impl FnOnce(
405405
AllocId,
406406
Size,
407-
Pointer<M::PointerTag>,
407+
M::PointerTag,
408408
) -> InterpResult<'tcx, (Size, Align, T)>,
409409
) -> InterpResult<'tcx, Option<T>> {
410410
fn check_offset_align(offset: u64, align: Align) -> InterpResult<'static> {
@@ -433,8 +433,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
433433
}
434434
None
435435
}
436-
Ok((alloc_id, offset, ptr)) => {
437-
let (alloc_size, alloc_align, ret_val) = alloc_size(alloc_id, offset, ptr)?;
436+
Ok((alloc_id, offset, tag)) => {
437+
let (alloc_size, alloc_align, ret_val) = alloc_size(alloc_id, offset, tag)?;
438438
// Test bounds. This also ensures non-null.
439439
// It is sufficient to check this for the end pointer. Also check for overflow!
440440
if offset.checked_add(size, &self.tcx).map_or(true, |end| end > alloc_size) {
@@ -450,10 +450,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
450450
// we want the error to be about the bounds.
451451
if let Some(align) = align {
452452
if M::force_int_for_alignment_check(self) {
453-
let addr = Scalar::from_pointer(ptr, &self.tcx)
454-
.to_machine_usize(&self.tcx)
455-
.expect("ptr-to-int cast for align check should never fail");
456-
check_offset_align(addr, align)?;
453+
assert!(M::PointerTag::OFFSET_IS_ADDR, "ptr-to-int cast for align check should never fail");
454+
let (_, addr) = ptr.into_parts(); // we checked that offset is absolute
455+
check_offset_align(addr.bytes(), align)?;
457456
} else {
458457
// Check allocation alignment and offset alignment.
459458
if alloc_align.bytes() < align.bytes() {
@@ -569,14 +568,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
569568
size,
570569
align,
571570
CheckInAllocMsg::MemoryAccessTest,
572-
|alloc_id, offset, ptr| {
571+
|alloc_id, offset, tag| {
573572
let alloc = self.get_alloc_raw(alloc_id)?;
574-
Ok((alloc.size(), alloc.align, (alloc_id, offset, ptr, alloc)))
573+
Ok((alloc.size(), alloc.align, (alloc_id, offset, tag, alloc)))
575574
},
576575
)?;
577-
if let Some((alloc_id, offset, ptr, alloc)) = ptr_and_alloc {
576+
if let Some((alloc_id, offset, tag, alloc)) = ptr_and_alloc {
578577
let range = alloc_range(offset, size);
579-
M::memory_read(*self.tcx, &self.machine, &alloc.extra, ptr.provenance, range)?;
578+
M::memory_read(*self.tcx, &self.machine, &alloc.extra, tag, range)?;
580579
Ok(Some(AllocRef { alloc, range, tcx: *self.tcx, alloc_id }))
581580
} else {
582581
// Even in this branch we have to be sure that we actually access the allocation, in
@@ -631,13 +630,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
631630
align: Align,
632631
) -> InterpResult<'tcx, Option<AllocRefMut<'a, 'tcx, M::PointerTag, M::AllocExtra>>> {
633632
let parts = self.get_ptr_access(ptr, size, align)?;
634-
if let Some((alloc_id, offset, ptr)) = parts {
633+
if let Some((alloc_id, offset, tag)) = parts {
635634
let tcx = *self.tcx;
636635
// FIXME: can we somehow avoid looking up the allocation twice here?
637636
// We cannot call `get_raw_mut` inside `check_and_deref_ptr` as that would duplicate `&mut self`.
638637
let (alloc, machine) = self.get_alloc_raw_mut(alloc_id)?;
639638
let range = alloc_range(offset, size);
640-
M::memory_written(tcx, machine, &mut alloc.extra, ptr.provenance, range)?;
639+
M::memory_written(tcx, machine, &mut alloc.extra, tag, range)?;
641640
Ok(Some(AllocRefMut { alloc, range, tcx, alloc_id }))
642641
} else {
643642
Ok(None)
@@ -732,7 +731,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
732731
ptr: Pointer<Option<M::PointerTag>>,
733732
) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> {
734733
trace!("get_fn({:?})", ptr);
735-
let (alloc_id, offset, _ptr) = self.ptr_get_alloc_id(ptr)?;
734+
let (alloc_id, offset, _tag) = self.ptr_get_alloc_id(ptr)?;
736735
if offset.bytes() != 0 {
737736
throw_ub!(InvalidFunctionPointer(Pointer::new(alloc_id, offset)))
738737
}
@@ -1009,16 +1008,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
10091008
// and once below to get the underlying `&[mut] Allocation`.
10101009

10111010
// Source alloc preparations and access hooks.
1012-
let Some((src_alloc_id, src_offset, src)) = src_parts else {
1011+
let Some((src_alloc_id, src_offset, src_tag)) = src_parts else {
10131012
// Zero-sized *source*, that means dst is also zero-sized and we have nothing to do.
10141013
return Ok(());
10151014
};
10161015
let src_alloc = self.get_alloc_raw(src_alloc_id)?;
10171016
let src_range = alloc_range(src_offset, size);
1018-
M::memory_read(*tcx, &self.machine, &src_alloc.extra, src.provenance, src_range)?;
1017+
M::memory_read(*tcx, &self.machine, &src_alloc.extra, src_tag, src_range)?;
10191018
// We need the `dest` ptr for the next operation, so we get it now.
10201019
// We already did the source checks and called the hooks so we are good to return early.
1021-
let Some((dest_alloc_id, dest_offset, dest)) = dest_parts else {
1020+
let Some((dest_alloc_id, dest_offset, dest_tag)) = dest_parts else {
10221021
// Zero-sized *destination*.
10231022
return Ok(());
10241023
};
@@ -1040,7 +1039,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
10401039
// Destination alloc preparations and access hooks.
10411040
let (dest_alloc, extra) = self.get_alloc_raw_mut(dest_alloc_id)?;
10421041
let dest_range = alloc_range(dest_offset, size * num_copies);
1043-
M::memory_written(*tcx, extra, &mut dest_alloc.extra, dest.provenance, dest_range)?;
1042+
M::memory_written(*tcx, extra, &mut dest_alloc.extra, dest_tag, dest_range)?;
10441043
let dest_bytes = dest_alloc
10451044
.get_bytes_mut_ptr(&tcx, dest_range)
10461045
.map_err(|e| e.to_interp_error(dest_alloc_id))?
@@ -1159,11 +1158,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
11591158
pub fn ptr_try_get_alloc_id(
11601159
&self,
11611160
ptr: Pointer<Option<M::PointerTag>>,
1162-
) -> Result<(AllocId, Size, Pointer<M::PointerTag>), u64> {
1161+
) -> Result<(AllocId, Size, M::PointerTag), u64> {
11631162
match ptr.into_pointer_or_addr() {
11641163
Ok(ptr) => {
11651164
let (alloc_id, offset) = M::ptr_get_alloc(self, ptr);
1166-
Ok((alloc_id, offset, ptr))
1165+
Ok((alloc_id, offset, ptr.provenance))
11671166
}
11681167
Err(addr) => Err(addr.bytes()),
11691168
}
@@ -1174,7 +1173,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
11741173
pub fn ptr_get_alloc_id(
11751174
&self,
11761175
ptr: Pointer<Option<M::PointerTag>>,
1177-
) -> InterpResult<'tcx, (AllocId, Size, Pointer<M::PointerTag>)> {
1176+
) -> InterpResult<'tcx, (AllocId, Size, M::PointerTag)> {
11781177
self.ptr_try_get_alloc_id(ptr).map_err(|offset| {
11791178
err_ub!(DanglingIntPointer(offset, CheckInAllocMsg::InboundsTest)).into()
11801179
})

compiler/rustc_const_eval/src/interpret/validity.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
432432
if let Some(ref mut ref_tracking) = self.ref_tracking {
433433
// Proceed recursively even for ZST, no reason to skip them!
434434
// `!` is a ZST and we want to validate it.
435-
if let Ok((alloc_id, _offset, _ptr)) = self.ecx.ptr_try_get_alloc_id(place.ptr) {
435+
if let Ok((alloc_id, _offset, _tag)) = self.ecx.ptr_try_get_alloc_id(place.ptr) {
436436
// Special handling for pointers to statics (irrespective of their type).
437437
let alloc_kind = self.ecx.tcx.get_global_alloc(alloc_id);
438438
if let Some(GlobalAlloc::Static(did)) = alloc_kind {

0 commit comments

Comments
 (0)