@@ -142,8 +142,9 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'a, 'mir, '
142142 // allocations sit right next to each other. The C/C++ standards are
143143 // somewhat fuzzy about this case, so I think for now this check is
144144 // "good enough".
145- self . memory ( ) . check_bounds_ptr ( left, false ) ?;
146- self . memory ( ) . check_bounds_ptr ( right, false ) ?;
145+ // We require liveness, as dead allocations can of course overlap.
146+ self . memory ( ) . check_bounds_ptr ( left, InboundsCheck :: Live ) ?;
147+ self . memory ( ) . check_bounds_ptr ( right, InboundsCheck :: Live ) ?;
147148 // Two live in-bounds pointers, we can compare across allocations
148149 left == right
149150 }
@@ -153,15 +154,17 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'a, 'mir, '
153154 ( Scalar :: Bits { bits, size } , Scalar :: Ptr ( ptr) ) => {
154155 assert_eq ! ( size as u64 , self . pointer_size( ) . bytes( ) ) ;
155156 let bits = bits as u64 ;
156- let ( alloc_size, alloc_align) = self . memory ( ) . get_size_and_align ( ptr. alloc_id ) ;
157157
158158 // Case I: Comparing with NULL
159159 if bits == 0 {
160160 // Test if the ptr is in-bounds. Then it cannot be NULL.
161- if ptr . offset <= alloc_size {
161+ if self . memory ( ) . check_bounds_ptr ( ptr , InboundsCheck :: MaybeDead ) . is_ok ( ) {
162162 return Ok ( false ) ;
163163 }
164164 }
165+
166+ let ( alloc_size, alloc_align) = self . memory ( ) . get_size_and_align ( ptr. alloc_id ) ;
167+
165168 // Case II: Alignment gives it away
166169 if ptr. offset . bytes ( ) % alloc_align. abi ( ) == 0 {
167170 // The offset maintains the allocation alignment, so we know `base+offset`
@@ -293,11 +296,11 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'a, 'mir, '
293296 let offset = offset. checked_mul ( pointee_size) . ok_or_else ( || EvalErrorKind :: Overflow ( mir:: BinOp :: Mul ) ) ?;
294297 // Now let's see what kind of pointer this is
295298 if let Scalar :: Ptr ( ptr) = ptr {
296- // Both old and new pointer must be in-bounds.
299+ // Both old and new pointer must be in-bounds of a *live* allocation .
297300 // (Of the same allocation, but that part is trivial with our representation.)
298- self . memory ( ) . check_bounds_ptr ( ptr, false ) ?;
301+ self . memory ( ) . check_bounds_ptr ( ptr, InboundsCheck :: Live ) ?;
299302 let ptr = ptr. signed_offset ( offset, self ) ?;
300- self . memory ( ) . check_bounds_ptr ( ptr, false ) ?;
303+ self . memory ( ) . check_bounds_ptr ( ptr, InboundsCheck :: Live ) ?;
301304 Ok ( Scalar :: Ptr ( ptr) )
302305 } else {
303306 // An integer pointer. They can only be offset by 0, and we pretend there
0 commit comments