@@ -116,21 +116,26 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
116
116
let this = self . eval_context_ref ( ) ;
117
117
let info = this. get_alloc_info ( alloc_id) ;
118
118
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 ( ) ;
127
119
// This is either called immediately after allocation (and then cached), or when
128
120
// adjusting `tcx` pointers (which never get freed). So assert that we are looking
129
121
// at a live allocation. This also ensures that we never re-assign an address to an
130
122
// allocation that previously had an address, but then was freed and the address
131
123
// information was removed.
132
124
assert ! ( !matches!( info. kind, AllocKind :: Dead ) ) ;
133
125
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
+
134
139
// This allocation does not have a base address yet, pick or reuse one.
135
140
if !this. machine . native_lib . is_empty ( ) {
136
141
// 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> {
157
162
this. get_alloc_bytes_unchecked_raw ( alloc_id) ?
158
163
}
159
164
}
160
- AllocKind :: Function | AllocKind :: Virtual => {
165
+ AllocKind :: Function | AllocKind :: VTable => {
161
166
// Allocate some dummy memory to get a unique address for this function/vtable.
162
167
let alloc_bytes = MiriAllocBytes :: from_bytes (
163
168
& [ 0u8 ; 1 ] ,
@@ -169,12 +174,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
169
174
std:: mem:: forget ( alloc_bytes) ;
170
175
ptr
171
176
}
172
- AllocKind :: Dead => unreachable ! ( ) ,
177
+ AllocKind :: TypeId | AllocKind :: Dead => unreachable ! ( ) ,
173
178
} ;
174
179
// We don't have to expose this pointer yet, we do that in `prepare_for_native_call`.
175
180
return interp_ok ( base_ptr. addr ( ) . to_u64 ( ) ) ;
176
181
}
177
182
// We are not in native lib mode, so we control the addresses ourselves.
183
+ let mut rng = this. machine . rng . borrow_mut ( ) ;
178
184
if let Some ( ( reuse_addr, clock) ) = global_state. reuse . take_addr (
179
185
& mut * rng,
180
186
info. size ,
0 commit comments