Skip to content

Commit 6085865

Browse files
committed
adjust for InboundsCheck parameter of memory bounds check
1 parent b8486ce commit 6085865

File tree

3 files changed

+14
-11
lines changed

3 files changed

+14
-11
lines changed

src/operator.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/stacked_borrows.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc::hir::{Mutability, MutMutable, MutImmutable};
55

66
use crate::{
77
EvalResult, EvalErrorKind, MiriEvalContext, HelpersEvalContextExt, Evaluator, MutValueVisitor,
8-
MemoryKind, MiriMemoryKind, RangeMap, AllocId, Allocation, AllocationExtra,
8+
MemoryKind, MiriMemoryKind, RangeMap, AllocId, Allocation, AllocationExtra, InboundsCheck,
99
Pointer, MemPlace, Scalar, Immediate, ImmTy, PlaceTy, MPlaceTy,
1010
};
1111

@@ -523,7 +523,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
523523
}
524524

525525
// Get the allocation
526-
self.memory().check_bounds(ptr, size, false)?;
526+
self.memory().check_bounds(ptr, size, InboundsCheck::Live)?;
527527
let alloc = self.memory().get(ptr.alloc_id).expect("We checked that the ptr is fine!");
528528
// If we got here, we do some checking, *but* we leave the tag unchanged.
529529
if let Borrow::Shr(Some(_)) = ptr.tag {
@@ -566,7 +566,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
566566
ptr, place.layout.ty, new_bor);
567567

568568
// Get the allocation. It might not be mutable, so we cannot use `get_mut`.
569-
self.memory().check_bounds(ptr, size, false)?;
569+
self.memory().check_bounds(ptr, size, InboundsCheck::Live)?;
570570
let alloc = self.memory().get(ptr.alloc_id).expect("We checked that the ptr is fine!");
571571
// Update the stacks.
572572
if let Borrow::Shr(Some(_)) = new_bor {

tests/compile-fail-fullmir/out_of_bounds_ptr_1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// error-pattern: pointer computed at offset 5, outside bounds of allocation
1+
// error-pattern: must be in-bounds and live at offset 5, but is outside bounds of allocation
22
fn main() {
33
let v = [0i8; 4];
44
let x = &v as *const i8;

0 commit comments

Comments
 (0)