@@ -142,8 +142,9 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'a, 'mir, '
142
142
// allocations sit right next to each other. The C/C++ standards are
143
143
// somewhat fuzzy about this case, so I think for now this check is
144
144
// "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 ) ?;
147
148
// Two live in-bounds pointers, we can compare across allocations
148
149
left == right
149
150
}
@@ -153,15 +154,17 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'a, 'mir, '
153
154
( Scalar :: Bits { bits, size } , Scalar :: Ptr ( ptr) ) => {
154
155
assert_eq ! ( size as u64 , self . pointer_size( ) . bytes( ) ) ;
155
156
let bits = bits as u64 ;
156
- let ( alloc_size, alloc_align) = self . memory ( ) . get_size_and_align ( ptr. alloc_id ) ;
157
157
158
158
// Case I: Comparing with NULL
159
159
if bits == 0 {
160
160
// 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 ( ) {
162
162
return Ok ( false ) ;
163
163
}
164
164
}
165
+
166
+ let ( alloc_size, alloc_align) = self . memory ( ) . get_size_and_align ( ptr. alloc_id ) ;
167
+
165
168
// Case II: Alignment gives it away
166
169
if ptr. offset . bytes ( ) % alloc_align. abi ( ) == 0 {
167
170
// 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, '
293
296
let offset = offset. checked_mul ( pointee_size) . ok_or_else ( || EvalErrorKind :: Overflow ( mir:: BinOp :: Mul ) ) ?;
294
297
// Now let's see what kind of pointer this is
295
298
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 .
297
300
// (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 ) ?;
299
302
let ptr = ptr. signed_offset ( offset, self ) ?;
300
- self . memory ( ) . check_bounds_ptr ( ptr, false ) ?;
303
+ self . memory ( ) . check_bounds_ptr ( ptr, InboundsCheck :: Live ) ?;
301
304
Ok ( Scalar :: Ptr ( ptr) )
302
305
} else {
303
306
// An integer pointer. They can only be offset by 0, and we pretend there
0 commit comments