mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-16 04:55:22 +03:00
Rebase fallout
This commit is contained in:
@@ -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".
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
use ty::layout::{self, HasDataLayout, Size};
|
||||
|
||||
use super::{
|
||||
AllocId, EvalResult,
|
||||
AllocId, EvalResult, InboundsCheck,
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -148,4 +148,21 @@ pub fn wrapping_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> Self {
|
||||
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(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
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)]
|
||||
@@ -251,9 +251,7 @@ pub fn check_align(
|
||||
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 } => {
|
||||
@@ -284,6 +282,23 @@ pub fn check_align(
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
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;
|
||||
@@ -647,7 +647,7 @@ pub fn read_discriminant(
|
||||
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()));
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
use rustc::ty;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc::mir::interpret::{
|
||||
Scalar, AllocType, EvalResult, EvalErrorKind, InboundsCheck,
|
||||
Scalar, AllocType, EvalResult, EvalErrorKind,
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
||||
+1
-1
Submodule src/tools/miri updated: dd7f545a69...32e93ed776
Reference in New Issue
Block a user