mirror of
https://github.com/rust-lang/rust.git
synced 2026-06-01 14:10:03 +03:00
validate boxes
This commit is contained in:
committed by
Oliver Schneider
parent
22f43e2d2b
commit
a91ee4bb03
@@ -2,6 +2,7 @@
|
||||
use rustc::mir;
|
||||
use rustc::ty::layout::{Size, Align};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::middle::region::CodeExtent;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use syntax::ast::Mutability;
|
||||
|
||||
@@ -469,7 +470,7 @@ pub(super) fn lvalue_ty(&self, lvalue: &mir::Lvalue<'tcx>) -> Ty<'tcx> {
|
||||
|
||||
// Validity checks
|
||||
impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
fn variant_check_valid(
|
||||
fn validate_variant(
|
||||
&mut self,
|
||||
lvalue: Lvalue<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
@@ -486,6 +487,20 @@ fn variant_check_valid(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_ptr(&mut self, val: Value, region: Option<CodeExtent>, pointee_ty: Ty<'tcx>, mutbl: TyMutability) -> EvalResult<'tcx> {
|
||||
use self::TyMutability::*;
|
||||
|
||||
// Acquire lock
|
||||
let (len, _) = self.size_and_align_of_dst(pointee_ty, val)?;
|
||||
let ptr = val.into_ptr(&mut self.memory)?.to_ptr()?;
|
||||
let access = match mutbl { MutMutable => AccessKind::Write, MutImmutable => AccessKind::Read };
|
||||
self.memory.acquire_lock(ptr, len, region, access)?;
|
||||
|
||||
// Recurse
|
||||
let pointee_lvalue = self.val_to_lvalue(val, pointee_ty)?;
|
||||
self.acquire_valid(pointee_lvalue, pointee_ty, mutbl)
|
||||
}
|
||||
|
||||
pub(super) fn acquire_valid(&mut self, lvalue: Lvalue<'tcx>, ty: Ty<'tcx>, outer_mutbl: TyMutability) -> EvalResult<'tcx> {
|
||||
use rustc::ty::TypeVariants::*;
|
||||
use rustc::ty::RegionKind::*;
|
||||
@@ -504,21 +519,18 @@ pub(super) fn acquire_valid(&mut self, lvalue: Lvalue<'tcx>, ty: Ty<'tcx>, outer
|
||||
Ok(())
|
||||
}
|
||||
TyRef(region, ty::TypeAndMut { ty: pointee_ty, mutbl }) => {
|
||||
// Acquire lock
|
||||
let val = self.read_lvalue(lvalue)?;
|
||||
let (len, _) = self.size_and_align_of_dst(pointee_ty, val)?;
|
||||
let ptr = val.into_ptr(&mut self.memory)?.to_ptr()?;
|
||||
let combined_mutbl = match outer_mutbl { MutMutable => mutbl, MutImmutable => MutImmutable };
|
||||
let access = match combined_mutbl { MutMutable => AccessKind::Write, MutImmutable => AccessKind::Read };
|
||||
let region = match *region {
|
||||
let extent = match *region {
|
||||
ReScope(extent) => Some(extent),
|
||||
_ => None,
|
||||
};
|
||||
self.memory.acquire_lock(ptr, len, region, access)?;
|
||||
|
||||
// Recurse
|
||||
let pointee_lvalue = self.val_to_lvalue(val, pointee_ty)?;
|
||||
self.acquire_valid(pointee_lvalue, pointee_ty, combined_mutbl)
|
||||
self.validate_ptr(val, extent, pointee_ty, combined_mutbl)
|
||||
}
|
||||
TyAdt(adt, _) if adt.is_box() => {
|
||||
let val = self.read_lvalue(lvalue)?;
|
||||
// TODO: The region can't always be None. It must take outer borrows into account.
|
||||
self.validate_ptr(val, None, ty.boxed_ty(), outer_mutbl)
|
||||
}
|
||||
TySlice(elem_ty) => {
|
||||
let len = match lvalue {
|
||||
@@ -555,10 +567,10 @@ pub(super) fn acquire_valid(&mut self, lvalue: Lvalue<'tcx>, ty: Ty<'tcx>, outer
|
||||
|
||||
// Recursively validate the fields
|
||||
let variant = &adt.variants[variant_idx];
|
||||
self.variant_check_valid(lvalue, ty, variant, subst, outer_mutbl)
|
||||
self.validate_variant(lvalue, ty, variant, subst, outer_mutbl)
|
||||
}
|
||||
AdtKind::Struct => {
|
||||
self.variant_check_valid(lvalue, ty, adt.struct_variant(), subst, outer_mutbl)
|
||||
self.validate_variant(lvalue, ty, adt.struct_variant(), subst, outer_mutbl)
|
||||
}
|
||||
AdtKind::Union => {
|
||||
// No guarantees are provided for union types.
|
||||
|
||||
Reference in New Issue
Block a user