11use log:: trace;
22
3- use rustc_target:: abi:: { Abi , Size } ;
3+ use rustc_target:: abi:: { Abi , Align , Size } ;
44
55use crate :: borrow_tracker:: { AccessKind , GlobalStateInner , ProtectorKind , RetagFields } ;
66use rustc_middle:: {
@@ -182,6 +182,8 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
182182 new_tag : BorTag ,
183183 ) -> InterpResult < ' tcx , Option < ( AllocId , BorTag ) > > {
184184 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 ) ?;
185187
186188 // It is crucial that this gets called on all code paths, to ensure we track tag creation.
187189 let log_creation = |this : & MiriInterpCx < ' mir , ' tcx > ,
@@ -202,51 +204,33 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
202204 } ;
203205
204206 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 ) ;
222225 }
223226 } ;
227+ log_creation ( this, Some ( ( alloc_id, base_offset, parent_prov) ) ) ?;
228+
224229 let orig_tag = match parent_prov {
225230 ProvenanceExtra :: Wildcard => return Ok ( None ) , // TODO: handle wildcard pointers
226231 ProvenanceExtra :: Concrete ( tag) => tag,
227232 } ;
228233
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-
250234 trace ! (
251235 "reborrow: reference {:?} derived from {:?} (pointee {}): {:?}, size {}" ,
252236 new_tag,
0 commit comments