1
1
use log:: trace;
2
2
3
- use rustc_target:: abi:: { Abi , Size } ;
3
+ use rustc_target:: abi:: { Abi , Align , Size } ;
4
4
5
5
use crate :: borrow_tracker:: { AccessKind , GlobalStateInner , ProtectorKind , RetagFields } ;
6
6
use rustc_middle:: {
@@ -182,6 +182,8 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
182
182
new_tag : BorTag ,
183
183
) -> InterpResult < ' tcx , Option < ( AllocId , BorTag ) > > {
184
184
let this = self . eval_context_mut ( ) ;
185
+ // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
186
+ this. check_ptr_access_align ( place. ptr , ptr_size, Align :: ONE , CheckInAllocMsg :: InboundsTest ) ?;
185
187
186
188
// It is crucial that this gets called on all code paths, to ensure we track tag creation.
187
189
let log_creation = |this : & MiriInterpCx < ' mir , ' tcx > ,
@@ -202,51 +204,33 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
202
204
} ;
203
205
204
206
trace ! ( "Reborrow of size {:?}" , ptr_size) ;
205
- let ( alloc_id, base_offset, parent_prov) = if ptr_size > Size :: ZERO {
206
- this. ptr_get_alloc_id ( place. ptr ) ?
207
- } else {
208
- match this. ptr_try_get_alloc_id ( place. ptr ) {
209
- Ok ( data) => data,
210
- Err ( _) => {
211
- // This pointer doesn't come with an AllocId, so there's no
212
- // memory to do retagging in.
213
- trace ! (
214
- "reborrow of size 0: reference {:?} derived from {:?} (pointee {})" ,
215
- new_tag,
216
- place. ptr,
217
- place. layout. ty,
218
- ) ;
219
- log_creation ( this, None ) ?;
220
- return Ok ( None ) ;
221
- }
207
+ let ( alloc_id, base_offset, parent_prov) = match this. ptr_try_get_alloc_id ( place. ptr ) {
208
+ Ok ( data) => {
209
+ // Unlike SB, we *do* a proper retag for size 0 if can identify the allocation.
210
+ // After all, the pointer may be lazily initialized outside this initial range.
211
+ data
212
+ } ,
213
+ Err ( _) => {
214
+ assert_eq ! ( ptr_size, Size :: ZERO ) ; // we did the deref check above, size has to be 0 here
215
+ // This pointer doesn't come with an AllocId, so there's no
216
+ // memory to do retagging in.
217
+ trace ! (
218
+ "reborrow of size 0: reference {:?} derived from {:?} (pointee {})" ,
219
+ new_tag,
220
+ place. ptr,
221
+ place. layout. ty,
222
+ ) ;
223
+ log_creation ( this, None ) ?;
224
+ return Ok ( None ) ;
222
225
}
223
226
} ;
227
+ log_creation ( this, Some ( ( alloc_id, base_offset, parent_prov) ) ) ?;
228
+
224
229
let orig_tag = match parent_prov {
225
230
ProvenanceExtra :: Wildcard => return Ok ( None ) , // TODO: handle wildcard pointers
226
231
ProvenanceExtra :: Concrete ( tag) => tag,
227
232
} ;
228
233
229
- // Protection against trying to get a reference to a vtable:
230
- // vtables do not have an alloc_extra so the call to
231
- // `get_alloc_extra` that follows fails.
232
- let ( alloc_size, _align, alloc_kind) = this. get_alloc_info ( alloc_id) ;
233
- if ptr_size == Size :: ZERO && !matches ! ( alloc_kind, AllocKind :: LiveData ) {
234
- return Ok ( Some ( ( alloc_id, orig_tag) ) ) ;
235
- }
236
-
237
- log_creation ( this, Some ( ( alloc_id, base_offset, parent_prov) ) ) ?;
238
-
239
- // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050).
240
- if base_offset + ptr_size > alloc_size {
241
- throw_ub ! ( PointerOutOfBounds {
242
- alloc_id,
243
- alloc_size,
244
- ptr_offset: this. target_usize_to_isize( base_offset. bytes( ) ) ,
245
- ptr_size,
246
- msg: CheckInAllocMsg :: InboundsTest
247
- } ) ;
248
- }
249
-
250
234
trace ! (
251
235
"reborrow: reference {:?} derived from {:?} (pointee {}): {:?}, size {}" ,
252
236
new_tag,
0 commit comments