@@ -152,8 +152,9 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'a, 'mir, '
152152 // This accepts one-past-the end. Thus, there is still technically
153153 // some non-determinism that we do not fully rule out when two
154154 // allocations sit right next to each other. The C/C++ standards are
155- // somewhat fuzzy about this case, so I think for now this check is
156- // "good enough".
155+ // somewhat fuzzy about this case, so pragmatically speaking I think
156+ // for now this check is "good enough".
157+ // FIXME: Once we support intptrcast, we could try to fix these holes.
157158 // Dead allocations in miri cannot overlap with live allocations, but
158159 // on read hardware this can easily happen. Thus for comparisons we require
159160 // both pointers to be live.
@@ -169,8 +170,17 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'a, 'mir, '
169170 assert_eq ! ( size as u64 , self . pointer_size( ) . bytes( ) ) ;
170171 let bits = bits as u64 ;
171172
172- // Case I: Comparing with NULL.
173- if bits == 0 {
173+ // Case I: Comparing real pointers with "small" integers.
174+ // Really we should only do this for NULL, but pragmatically speaking on non-bare-metal systems,
175+ // an allocation will never be at the very bottom of the address space.
176+ // Such comparisons can arise when comparing empty slices, which sometimes are "fake"
177+ // integer pointers (okay because the slice is empty) and sometimes point into a
178+ // real allocation.
179+ // The most common source of such integer pointers is `NonNull::dangling()`, which
180+ // equals the type's alignment. i128 might have an alignment of 16 bytes, but few types have
181+ // alignment 32 or higher, hence the limit of 32.
182+ // FIXME: Once we support intptrcast, we could try to fix these holes.
183+ if bits < 32 {
174184 // Test if the ptr is in-bounds. Then it cannot be NULL.
175185 // Even dangling pointers cannot be NULL.
176186 if self . memory ( ) . check_bounds_ptr ( ptr, InboundsCheck :: MaybeDead ) . is_ok ( ) {
0 commit comments