@@ -116,21 +116,26 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
116116 let this = self . eval_context_ref ( ) ;
117117 let info = this. get_alloc_info ( alloc_id) ;
118118
119- // Miri's address assignment leaks state across thread boundaries, which is incompatible
120- // with GenMC execution. So we instead let GenMC assign addresses to allocations.
121- if let Some ( genmc_ctx) = this. machine . data_race . as_genmc_ref ( ) {
122- let addr = genmc_ctx. handle_alloc ( & this. machine , info. size , info. align , memory_kind) ?;
123- return interp_ok ( addr) ;
124- }
125-
126- let mut rng = this. machine . rng . borrow_mut ( ) ;
127119 // This is either called immediately after allocation (and then cached), or when
128120 // adjusting `tcx` pointers (which never get freed). So assert that we are looking
129121 // at a live allocation. This also ensures that we never re-assign an address to an
130122 // allocation that previously had an address, but then was freed and the address
131123 // information was removed.
132124 assert ! ( !matches!( info. kind, AllocKind :: Dead ) ) ;
133125
126+ // TypeId allocations always have a "base address" of 0 (i.e., the relative offset is the
127+ // hash fragment and therefore equal to the actual integer value).
128+ if matches ! ( info. kind, AllocKind :: TypeId ) {
129+ return interp_ok ( 0 ) ;
130+ }
131+
132+ // Miri's address assignment leaks state across thread boundaries, which is incompatible
133+ // with GenMC execution. So we instead let GenMC assign addresses to allocations.
134+ if let Some ( genmc_ctx) = this. machine . data_race . as_genmc_ref ( ) {
135+ let addr = genmc_ctx. handle_alloc ( & this. machine , info. size , info. align , memory_kind) ?;
136+ return interp_ok ( addr) ;
137+ }
138+
134139 // This allocation does not have a base address yet, pick or reuse one.
135140 if !this. machine . native_lib . is_empty ( ) {
136141 // In native lib mode, we use the "real" address of the bytes for this allocation.
@@ -157,7 +162,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
157162 this. get_alloc_bytes_unchecked_raw ( alloc_id) ?
158163 }
159164 }
160- AllocKind :: Function | AllocKind :: Virtual => {
165+ AllocKind :: Function | AllocKind :: VTable => {
161166 // Allocate some dummy memory to get a unique address for this function/vtable.
162167 let alloc_bytes = MiriAllocBytes :: from_bytes (
163168 & [ 0u8 ; 1 ] ,
@@ -169,12 +174,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
169174 std:: mem:: forget ( alloc_bytes) ;
170175 ptr
171176 }
172- AllocKind :: Dead => unreachable ! ( ) ,
177+ AllocKind :: TypeId | AllocKind :: Dead => unreachable ! ( ) ,
173178 } ;
174179 // We don't have to expose this pointer yet, we do that in `prepare_for_native_call`.
175180 return interp_ok ( base_ptr. addr ( ) . to_u64 ( ) ) ;
176181 }
177182 // We are not in native lib mode, so we control the addresses ourselves.
183+ let mut rng = this. machine . rng . borrow_mut ( ) ;
178184 if let Some ( ( reuse_addr, clock) ) = global_state. reuse . take_addr (
179185 & mut * rng,
180186 info. size ,
@@ -295,21 +301,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
295301 // Store address in cache.
296302 global_state. base_addr . try_insert ( alloc_id, base_addr) . unwrap ( ) ;
297303
298- // Also maintain the opposite mapping in `int_to_ptr_map`, ensuring we keep it sorted.
299- // We have a fast-path for the common case that this address is bigger than all previous ones.
300- let pos = if global_state
301- . int_to_ptr_map
302- . last ( )
303- . is_some_and ( |( last_addr, _) | * last_addr < base_addr)
304- {
305- global_state. int_to_ptr_map . len ( )
306- } else {
307- global_state
304+ // Also maintain the opposite mapping in `int_to_ptr_map`, ensuring we keep it
305+ // sorted. We have a fast-path for the common case that this address is bigger than
306+ // all previous ones. We skip this for allocations at address 0; those can't be
307+ // real, they must be TypeId "fake allocations".
308+ if base_addr != 0 {
309+ let pos = if global_state
308310 . int_to_ptr_map
309- . binary_search_by_key ( & base_addr, |( addr, _) | * addr)
310- . unwrap_err ( )
311- } ;
312- global_state. int_to_ptr_map . insert ( pos, ( base_addr, alloc_id) ) ;
311+ . last ( )
312+ . is_some_and ( |( last_addr, _) | * last_addr < base_addr)
313+ {
314+ global_state. int_to_ptr_map . len ( )
315+ } else {
316+ global_state
317+ . int_to_ptr_map
318+ . binary_search_by_key ( & base_addr, |( addr, _) | * addr)
319+ . unwrap_err ( )
320+ } ;
321+ global_state. int_to_ptr_map . insert ( pos, ( base_addr, alloc_id) ) ;
322+ }
313323
314324 interp_ok ( base_addr)
315325 }
0 commit comments