X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_mir%2Finterpret%2Fvalidity.rs;h=072c6f4fd90e8e9641bcf2264246bc025050f2ab;hb=9121a73ab1d474d5cdba44b566c782eb2581e60b;hp=bd6f005e8736c992de7605eb6a60481934f47a10;hpb=c7fcbfbf1fff2794de5ec6dcb0a052c345ded3a7;p=rust.git diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index bd6f005e873..072c6f4fd90 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -2,13 +2,13 @@ use std::hash::Hash; use std::ops::RangeInclusive; -use syntax_pos::symbol::Symbol; +use syntax_pos::symbol::{sym, Symbol}; use rustc::hir; use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf, VariantIdx}; use rustc::ty; use rustc_data_structures::fx::FxHashSet; use rustc::mir::interpret::{ - Scalar, AllocKind, EvalResult, InterpError, + Scalar, AllocKind, EvalResult, InterpError, CheckInAllocMsg, }; use super::{ @@ -66,6 +66,7 @@ macro_rules! try_validation { pub enum PathElem { Field(Symbol), Variant(Symbol), + GeneratorState(VariantIdx), ClosureVar(Symbol), ArrayElem(usize), TupleElem(usize), @@ -100,6 +101,7 @@ fn path_format(path: &Vec) -> String { match elem { Field(name) => write!(out, ".{}", name), Variant(name) => write!(out, ".", name), + GeneratorState(idx) => write!(out, ".", idx.index()), ClosureVar(name) => write!(out, ".", name), TupleElem(idx) => write!(out, ".{}", idx), ArrayElem(idx) => write!(out, "[{}]", idx), @@ -170,7 +172,7 @@ fn aggregate_field_path_elem( if def_id.is_local() { let tables = self.ecx.tcx.typeck_tables_of(def_id); if let Some(upvars) = tables.upvar_list.get(&def_id) { - // Sometimes the index is beyond the number of freevars (seen + // Sometimes the index is beyond the number of upvars (seen // for a generator). if let Some(upvar_id) = upvars.get(field) { let var_hir_id = upvar_id.var_path.hir_id; @@ -186,7 +188,7 @@ fn aggregate_field_path_elem( PathElem::ClosureVar(name.unwrap_or_else(|| { // Fall back to showing the field index. - Symbol::intern(&field.to_string()) + sym::integer(field) })) } @@ -262,8 +264,13 @@ fn visit_variant( variant_id: VariantIdx, new_op: OpTy<'tcx, M::PointerTag> ) -> EvalResult<'tcx> { - let name = old_op.layout.ty.ty_adt_def().unwrap().variants[variant_id].ident.name; - self.visit_elem(new_op, PathElem::Variant(name)) + let name = match old_op.layout.ty.sty { + ty::Adt(adt, _) => PathElem::Variant(adt.variants[variant_id].ident.name), + // Generators also have variants + ty::Generator(..) => PathElem::GeneratorState(variant_id), + _ => bug!("Unexpected type with variant: {:?}", old_op.layout.ty), + }; + self.visit_elem(new_op, name) } #[inline] @@ -410,7 +417,7 @@ fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> EvalResult<'t try_validation!( self.ecx.memory .get(ptr.alloc_id)? - .check_bounds(self.ecx, ptr, size), + .check_bounds(self.ecx, ptr, size, CheckInAllocMsg::InboundsTest), "dangling (not entirely in bounds) reference", self.path); } // Check if we have encountered this pointer+layout combination @@ -473,8 +480,8 @@ fn visit_scalar( wrapping_range_format(&layout.valid_range, max_hi), ) ); - let bits = match value { - Scalar::Ptr(ptr) => { + let bits = match value.to_bits_or_ptr(op.layout.size, self.ecx) { + Err(ptr) => { if lo == 1 && hi == max_hi { // only NULL is not allowed. // We can call `check_align` to check non-NULL-ness, but have to also look @@ -502,10 +509,8 @@ fn visit_scalar( ); } } - Scalar::Bits { bits, size } => { - assert_eq!(size as u64, op.layout.size.bytes()); - bits - } + Ok(data) => + data }; // Now compare. This is slightly subtle because this is a special "wrap-around" range. if wrapping_range_contains(&layout.valid_range, bits) {