Skip to content

Commit e3ae9f5

Browse files
authored
Rollup merge of #98099 - RalfJung:convert_tag_add_extra, r=oli-obk
interpret: convert_tag_add_extra: allow tagger to raise errors Needed for rust-lang/miri#2234 r? `@oli-obk`
2 parents fdeecb2 + 1c1a60f commit e3ae9f5

File tree

3 files changed

+21
-17
lines changed

3 files changed

+21
-17
lines changed

compiler/rustc_const_eval/src/interpret/machine.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -334,12 +334,14 @@ pub trait Machine<'mir, 'tcx>: Sized {
334334
/// allocation (because a copy had to be done to add tags or metadata), machine memory will
335335
/// cache the result. (This relies on `AllocMap::get_or` being able to add the
336336
/// owned allocation to the map even when the map is shared.)
337+
///
338+
/// This must only fail if `alloc` contains relocations.
337339
fn init_allocation_extra<'b>(
338340
ecx: &InterpCx<'mir, 'tcx, Self>,
339341
id: AllocId,
340342
alloc: Cow<'b, Allocation>,
341343
kind: Option<MemoryKind<Self::MemoryKind>>,
342-
) -> Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>;
344+
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>>;
343345

344346
/// Hook for performing extra checks on a memory read access.
345347
///
@@ -485,9 +487,9 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
485487
_id: AllocId,
486488
alloc: Cow<'b, Allocation>,
487489
_kind: Option<MemoryKind<Self::MemoryKind>>,
488-
) -> Cow<'b, Allocation<Self::PointerTag>> {
490+
) -> InterpResult<$tcx, Cow<'b, Allocation<Self::PointerTag>>> {
489491
// We do not use a tag so we can just cheaply forward the allocation
490-
alloc
492+
Ok(alloc)
491493
}
492494

493495
fn extern_static_base_pointer(

compiler/rustc_const_eval/src/interpret/memory.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
199199
kind: MemoryKind<M::MemoryKind>,
200200
) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
201201
let alloc = Allocation::uninit(size, align, M::PANIC_ON_ALLOC_FAIL)?;
202-
Ok(self.allocate_raw_ptr(alloc, kind))
202+
// We can `unwrap` since `alloc` contains no pointers.
203+
Ok(self.allocate_raw_ptr(alloc, kind).unwrap())
203204
}
204205

205206
pub fn allocate_bytes_ptr(
@@ -210,23 +211,25 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
210211
mutability: Mutability,
211212
) -> Pointer<M::PointerTag> {
212213
let alloc = Allocation::from_bytes(bytes, align, mutability);
213-
self.allocate_raw_ptr(alloc, kind)
214+
// We can `unwrap` since `alloc` contains no pointers.
215+
self.allocate_raw_ptr(alloc, kind).unwrap()
214216
}
215217

218+
/// This can fail only of `alloc` contains relocations.
216219
pub fn allocate_raw_ptr(
217220
&mut self,
218221
alloc: Allocation,
219222
kind: MemoryKind<M::MemoryKind>,
220-
) -> Pointer<M::PointerTag> {
223+
) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
221224
let id = self.tcx.reserve_alloc_id();
222225
debug_assert_ne!(
223226
Some(kind),
224227
M::GLOBAL_KIND.map(MemoryKind::Machine),
225228
"dynamically allocating global memory"
226229
);
227-
let alloc = M::init_allocation_extra(self, id, Cow::Owned(alloc), Some(kind));
230+
let alloc = M::init_allocation_extra(self, id, Cow::Owned(alloc), Some(kind))?;
228231
self.memory.alloc_map.insert(id, (kind, alloc.into_owned()));
229-
M::tag_alloc_base_pointer(self, Pointer::from(id))
232+
Ok(M::tag_alloc_base_pointer(self, Pointer::from(id)))
230233
}
231234

232235
pub fn reallocate_ptr(
@@ -510,13 +513,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
510513
};
511514
M::before_access_global(*self.tcx, &self.machine, id, alloc, def_id, is_write)?;
512515
// We got tcx memory. Let the machine initialize its "extra" stuff.
513-
let alloc = M::init_allocation_extra(
516+
M::init_allocation_extra(
514517
self,
515518
id, // always use the ID we got as input, not the "hidden" one.
516519
Cow::Borrowed(alloc.inner()),
517520
M::GLOBAL_KIND.map(MemoryKind::Machine),
518-
);
519-
Ok(alloc)
521+
)
520522
}
521523

522524
/// Gives raw access to the `Allocation`, without bounds or alignment checks.

compiler/rustc_middle/src/mir/interpret/allocation.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,12 @@ impl<Tag> Allocation<Tag> {
244244

245245
impl Allocation {
246246
/// Convert Tag and add Extra fields
247-
pub fn convert_tag_add_extra<Tag, Extra>(
247+
pub fn convert_tag_add_extra<Tag, Extra, Err>(
248248
self,
249249
cx: &impl HasDataLayout,
250250
extra: Extra,
251-
mut tagger: impl FnMut(Pointer<AllocId>) -> Pointer<Tag>,
252-
) -> Allocation<Tag, Extra> {
251+
mut tagger: impl FnMut(Pointer<AllocId>) -> Result<Pointer<Tag>, Err>,
252+
) -> Result<Allocation<Tag, Extra>, Err> {
253253
// Compute new pointer tags, which also adjusts the bytes.
254254
let mut bytes = self.bytes;
255255
let mut new_relocations = Vec::with_capacity(self.relocations.0.len());
@@ -260,19 +260,19 @@ impl Allocation {
260260
let ptr_bytes = &mut bytes[idx..idx + ptr_size];
261261
let bits = read_target_uint(endian, ptr_bytes).unwrap();
262262
let (ptr_tag, ptr_offset) =
263-
tagger(Pointer::new(alloc_id, Size::from_bytes(bits))).into_parts();
263+
tagger(Pointer::new(alloc_id, Size::from_bytes(bits)))?.into_parts();
264264
write_target_uint(endian, ptr_bytes, ptr_offset.bytes().into()).unwrap();
265265
new_relocations.push((offset, ptr_tag));
266266
}
267267
// Create allocation.
268-
Allocation {
268+
Ok(Allocation {
269269
bytes,
270270
relocations: Relocations::from_presorted(new_relocations),
271271
init_mask: self.init_mask,
272272
align: self.align,
273273
mutability: self.mutability,
274274
extra,
275-
}
275+
})
276276
}
277277
}
278278

0 commit comments

Comments
 (0)