diff options
| author | Ralf Jung <post@ralfj.de> | 2017-06-19 23:39:18 -0700 |
|---|---|---|
| committer | Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de> | 2017-07-25 10:20:45 +0200 |
| commit | a91ee4bb03a3e27cfea3da0b71e5458bccb2f298 (patch) | |
| tree | 8709ea5a6e3392eb76c54363342dd66ac6207293 /src | |
| parent | 22f43e2d2b2cdd5e6e6d771a01542a0e5afc6441 (diff) | |
| download | rust-a91ee4bb03a3e27cfea3da0b71e5458bccb2f298.tar.gz rust-a91ee4bb03a3e27cfea3da0b71e5458bccb2f298.zip | |
validate boxes
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_mir/interpret/lvalue.rs | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/src/librustc_mir/interpret/lvalue.rs b/src/librustc_mir/interpret/lvalue.rs index 78e09e3621d..6693b89baae 100644 --- a/src/librustc_mir/interpret/lvalue.rs +++ b/src/librustc_mir/interpret/lvalue.rs @@ -2,6 +2,7 @@ use rustc::hir::Mutability as TyMutability; 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 @@ impl<'a, 'tcx> EvalContext<'a, '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 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { 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 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { 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 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { // 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. |
