Skip to content

Commit

Permalink
Rebase fallout
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Nov 24, 2018
1 parent 360f988 commit b853252
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 21 deletions.
13 changes: 2 additions & 11 deletions src/librustc/mir/interpret/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,23 +57,14 @@ pub struct Allocation<Tag=(),Extra=()> {
impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
/// Check if the pointer is "in-bounds". Notice that a pointer pointing at the end
/// of an allocation (i.e., at the first *inaccessible* location) *is* considered
/// in-bounds! This follows C's/LLVM's rules. `check` indicates whether we
/// additionally require the pointer to be pointing to a *live* (still allocated)
/// allocation.
/// in-bounds! This follows C's/LLVM's rules.
/// If you want to check bounds before doing a memory access, better use `check_bounds`.
pub fn check_bounds_ptr(
&self,
ptr: Pointer<Tag>,
) -> EvalResult<'tcx> {
let allocation_size = self.bytes.len() as u64;
if ptr.offset.bytes() > allocation_size {
return err!(PointerOutOfBounds {
ptr: ptr.erase_tag(),
check: InboundsCheck::Live,
allocation_size: Size::from_bytes(allocation_size),
});
}
Ok(())
ptr.check_in_alloc(Size::from_bytes(allocation_size), InboundsCheck::Live)
}

/// Check if the memory range beginning at `ptr` and of size `Size` is "in-bounds".
Expand Down
19 changes: 18 additions & 1 deletion src/librustc/mir/interpret/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use mir;
use ty::layout::{self, HasDataLayout, Size};

use super::{
AllocId, EvalResult,
AllocId, EvalResult, InboundsCheck,
};

////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -148,4 +148,21 @@ impl<'tcx, Tag> Pointer<Tag> {
pub fn erase_tag(self) -> Pointer {
Pointer { alloc_id: self.alloc_id, offset: self.offset, tag: () }
}

#[inline(always)]
pub fn check_in_alloc(
self,
allocation_size: Size,
check: InboundsCheck,
) -> EvalResult<'tcx, ()> {
if self.offset > allocation_size {
err!(PointerOutOfBounds {
ptr: self.erase_tag(),
check,
allocation_size,
})
} else {
Ok(())
}
}
}
25 changes: 20 additions & 5 deletions src/librustc_mir/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ use rustc_data_structures::fx::{FxHashSet, FxHashMap};
use syntax::ast::Mutability;

use super::{
Pointer, AllocId, Allocation, GlobalId, AllocationExtra, InboundsCheck,
Pointer, AllocId, Allocation, GlobalId, AllocationExtra,
EvalResult, Scalar, EvalErrorKind, AllocType, PointerArithmetic,
Machine, AllocMap, MayLeak, ErrorHandled, AllocationExtra,
Machine, AllocMap, MayLeak, ErrorHandled, InboundsCheck,
};

#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
Expand Down Expand Up @@ -251,9 +251,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
Scalar::Ptr(ptr) => {
// check this is not NULL -- which we can ensure only if this is in-bounds
// of some (potentially dead) allocation.
self.check_bounds_ptr(ptr, InboundsCheck::MaybeDead)?;
// data required for alignment check
let (_, align) = self.get_size_and_align(ptr.alloc_id);
let align = self.check_bounds_ptr_maybe_dead(ptr)?;
(ptr.offset.bytes(), align)
}
Scalar::Bits { bits, size } => {
Expand Down Expand Up @@ -284,6 +282,23 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
})
}
}

/// Check if the pointer is "in-bounds". Notice that a pointer pointing at the end
/// of an allocation (i.e., at the first *inaccessible* location) *is* considered
/// in-bounds! This follows C's/LLVM's rules.
/// This function also works for deallocated allocations.
/// Use `.get(ptr.alloc_id)?.check_bounds_ptr(ptr)` if you want to force the allocation
/// to still be live.
/// If you want to check bounds before doing a memory access, better first obtain
/// an `Allocation` and call `check_bounds`.
pub fn check_bounds_ptr_maybe_dead(
&self,
ptr: Pointer<M::PointerTag>,
) -> EvalResult<'tcx, Align> {
let (allocation_size, align) = self.get_size_and_align(ptr.alloc_id);
ptr.check_in_alloc(allocation_size, InboundsCheck::MaybeDead)?;
Ok(align)
}
}

/// Allocation accessors
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerEx
use rustc::mir::interpret::{
GlobalId, AllocId,
ConstValue, Pointer, Scalar,
EvalResult, EvalErrorKind, InboundsCheck,
EvalResult, EvalErrorKind,
};
use super::{EvalContext, Machine, MemPlace, MPlaceTy, MemoryKind};
pub use rustc::mir::interpret::ScalarMaybeUndef;
Expand Down Expand Up @@ -647,7 +647,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
ScalarMaybeUndef::Scalar(Scalar::Ptr(ptr)) => {
// The niche must be just 0 (which an inbounds pointer value never is)
let ptr_valid = niche_start == 0 && variants_start == variants_end &&
self.memory.check_bounds_ptr(ptr, InboundsCheck::MaybeDead).is_ok();
self.memory.check_bounds_ptr_maybe_dead(ptr).is_ok();
if !ptr_valid {
return err!(InvalidDiscriminant(raw_discr.erase_tag()));
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf, VariantIdx};
use rustc::ty;
use rustc_data_structures::fx::FxHashSet;
use rustc::mir::interpret::{
Scalar, AllocType, EvalResult, EvalErrorKind, InboundsCheck,
Scalar, AllocType, EvalResult, EvalErrorKind,
};

use super::{
Expand Down
2 changes: 1 addition & 1 deletion src/tools/miri
Submodule miri updated from dd7f54 to 32e93e

0 comments on commit b853252

Please sign in to comment.