Skip to content

Commit 7c9d786

Browse files
committed
Move alignment and bounds check from Memory to Allocation
1 parent d98c46c commit 7c9d786

File tree

2 files changed

+45
-42
lines changed

2 files changed

+45
-42
lines changed

src/librustc/mir/interpret/allocation.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,51 @@ pub struct Allocation<Tag=(),Extra=()> {
4949
pub extra: Extra,
5050
}
5151

52+
/// Alignment and bounds checks
53+
impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
54+
/// Check if the pointer is "in-bounds". Notice that a pointer pointing at the end
55+
/// of an allocation (i.e., at the first *inaccessible* location) *is* considered
56+
/// in-bounds! This follows C's/LLVM's rules. `check` indicates whether we
57+
/// additionally require the pointer to be pointing to a *live* (still allocated)
58+
/// allocation.
59+
/// If you want to check bounds before doing a memory access, better use `check_bounds`.
60+
pub fn check_bounds_ptr(
61+
&self,
62+
ptr: Pointer<M::PointerTag>,
63+
check: InboundsCheck,
64+
) -> EvalResult<'tcx> {
65+
let allocation_size = match check {
66+
InboundsCheck::Live => {
67+
let alloc = self.get(ptr.alloc_id)?;
68+
alloc.bytes.len() as u64
69+
}
70+
InboundsCheck::MaybeDead => {
71+
self.get_size_and_align(ptr.alloc_id).0.bytes()
72+
}
73+
};
74+
if ptr.offset.bytes() > allocation_size {
75+
return err!(PointerOutOfBounds {
76+
ptr: ptr.erase_tag(),
77+
check,
78+
allocation_size: Size::from_bytes(allocation_size),
79+
});
80+
}
81+
Ok(())
82+
}
83+
84+
/// Check if the memory range beginning at `ptr` and of size `Size` is "in-bounds".
85+
#[inline(always)]
86+
pub fn check_bounds(
87+
&self,
88+
ptr: Pointer<M::PointerTag>,
89+
size: Size,
90+
check: InboundsCheck,
91+
) -> EvalResult<'tcx> {
92+
// if ptr.offset is in bounds, then so is ptr (because offset checks for overflow)
93+
self.check_bounds_ptr(ptr.offset(size, &*self)?, check)
94+
}
95+
}
96+
5297
/// Byte accessors
5398
impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
5499
/// The last argument controls whether we error out when there are undefined

src/librustc_mir/interpret/memory.rs

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -284,48 +284,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
284284
})
285285
}
286286
}
287-
288-
/// Check if the pointer is "in-bounds". Notice that a pointer pointing at the end
289-
/// of an allocation (i.e., at the first *inaccessible* location) *is* considered
290-
/// in-bounds! This follows C's/LLVM's rules. `check` indicates whether we
291-
/// additionally require the pointer to be pointing to a *live* (still allocated)
292-
/// allocation.
293-
/// If you want to check bounds before doing a memory access, better use `check_bounds`.
294-
pub fn check_bounds_ptr(
295-
&self,
296-
ptr: Pointer<M::PointerTag>,
297-
check: InboundsCheck,
298-
) -> EvalResult<'tcx> {
299-
let allocation_size = match check {
300-
InboundsCheck::Live => {
301-
let alloc = self.get(ptr.alloc_id)?;
302-
alloc.bytes.len() as u64
303-
}
304-
InboundsCheck::MaybeDead => {
305-
self.get_size_and_align(ptr.alloc_id).0.bytes()
306-
}
307-
};
308-
if ptr.offset.bytes() > allocation_size {
309-
return err!(PointerOutOfBounds {
310-
ptr: ptr.erase_tag(),
311-
check,
312-
allocation_size: Size::from_bytes(allocation_size),
313-
});
314-
}
315-
Ok(())
316-
}
317-
318-
/// Check if the memory range beginning at `ptr` and of size `Size` is "in-bounds".
319-
#[inline(always)]
320-
pub fn check_bounds(
321-
&self,
322-
ptr: Pointer<M::PointerTag>,
323-
size: Size,
324-
check: InboundsCheck,
325-
) -> EvalResult<'tcx> {
326-
// if ptr.offset is in bounds, then so is ptr (because offset checks for overflow)
327-
self.check_bounds_ptr(ptr.offset(size, &*self)?, check)
328-
}
329287
}
330288

331289
/// Allocation accessors

0 commit comments

Comments
 (0)