From: Oliver Schneider Date: Wed, 1 Aug 2018 10:55:05 +0000 (+0200) Subject: Address behaviour changing review comments X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=551df459357cb812443a5467f95bed4536b5b3ad;p=rust.git Address behaviour changing review comments --- diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 74d7186b90a..c9bb48d2756 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -218,15 +218,6 @@ pub fn to_value_with_vtable(self, vtable: Pointer) -> Value { Value::ScalarPair(self.into(), Scalar::Ptr(vtable).into()) } - pub fn ptr_signed_offset(self, i: i64, cx: C) -> EvalResult<'tcx, Self> { - match self { - ScalarMaybeUndef::Scalar(scalar) => { - scalar.ptr_signed_offset(i, cx).map(ScalarMaybeUndef::Scalar) - }, - ScalarMaybeUndef::Undef => Ok(ScalarMaybeUndef::Undef) - } - } - pub fn ptr_offset(self, i: Size, cx: C) -> EvalResult<'tcx, Self> { match self { ScalarMaybeUndef::Scalar(scalar) => { @@ -235,15 +226,6 @@ pub fn ptr_offset(self, i: Size, cx: C) -> EvalResult<'tcx, Se ScalarMaybeUndef::Undef => Ok(ScalarMaybeUndef::Undef) } } - - pub fn ptr_wrapping_signed_offset(self, i: i64, cx: C) -> Self { - match self { - ScalarMaybeUndef::Scalar(scalar) => { - ScalarMaybeUndef::Scalar(scalar.ptr_wrapping_signed_offset(i, cx)) - }, - ScalarMaybeUndef::Undef => ScalarMaybeUndef::Undef - } - } } impl<'tcx> Scalar { diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 2e4ed7afc22..b28858b0cf0 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -5,7 +5,7 @@ use rustc::mir::interpret::{ConstEvalErr, ScalarMaybeUndef}; use rustc::mir; use rustc::ty::{self, TyCtxt, Ty, Instance}; -use rustc::ty::layout::{self, LayoutOf, Primitive, TyLayout}; +use rustc::ty::layout::{self, LayoutOf, Primitive, TyLayout, Size}; use rustc::ty::subst::Subst; use rustc_data_structures::indexed_vec::IndexVec; @@ -76,9 +76,8 @@ pub fn eval_promoted<'a, 'mir, 'tcx>( pub fn value_to_const_value<'tcx>( ecx: &EvalContext<'_, '_, 'tcx, CompileTimeEvaluator>, val: Value, - ty: Ty<'tcx>, + layout: TyLayout<'tcx>, ) -> &'tcx ty::Const<'tcx> { - let layout = ecx.layout_of(ty).unwrap(); match (val, &layout.abi) { (Value::Scalar(ScalarMaybeUndef::Scalar(Scalar::Bits { size: 0, ..})), _) if layout.is_zst() => {}, (Value::ByRef(..), _) | @@ -103,19 +102,19 @@ pub fn value_to_const_value<'tcx>( } })(); match val { - Ok(val) => ty::Const::from_const_value(ecx.tcx.tcx, val, ty), - Err(err) => { - let (frames, span) = ecx.generate_stacktrace(None); - let err = ConstEvalErr { - span, - error: err, - stacktrace: frames, - }; - err.report_as_error( - ecx.tcx, - "failed to convert Value to ConstValue, this is a bug", - ); - span_bug!(span, "miri error occured when converting Value to ConstValue") + Ok(val) => ty::Const::from_const_value(ecx.tcx.tcx, val, layout.ty), + Err(error) => { + let (stacktrace, span) = ecx.generate_stacktrace(None); + let err = ConstEvalErr { span, error, stacktrace }; + if let Some(mut err) = err.struct_error(ecx.tcx, "failed to convert Value to ConstValue") { + err.delay_as_bug(); + } else { + span_bug!(span, "failed to convert Value to ConstValue") + } + let alloc = Allocation::undef(layout.size, layout.align); + let alloc = ecx.tcx.intern_const_alloc(alloc); + let val = ConstValue::ByRef(alloc, Size::ZERO); + ty::Const::from_const_value(ecx.tcx.tcx, val, layout.ty) } } } @@ -455,7 +454,7 @@ pub fn const_val_field<'a, 'tcx>( ), _ => {}, } - Ok(value_to_const_value(&ecx, new_value, layout.ty)) + Ok(value_to_const_value(&ecx, new_value, layout)) })(); result.map_err(|err| { let (trace, span) = ecx.generate_stacktrace(None); @@ -556,7 +555,7 @@ pub fn const_eval_provider<'a, 'tcx>( if tcx.is_static(def_id).is_none() && cid.promoted.is_none() { val = ecx.try_read_by_ref(val, layout.ty)?; } - Ok(value_to_const_value(&ecx, val, layout.ty)) + Ok(value_to_const_value(&ecx, val, layout)) }).map_err(|err| { let (trace, span) = ecx.generate_stacktrace(None); let err = ConstEvalErr { diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 7f32156592c..b4c9d157150 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -1261,7 +1261,7 @@ pub fn write_value_to_ptr( }, _ => false, }; - self.memory.write_scalar(dest, dest_align, scalar, layout.size, signed) + self.memory.write_scalar(dest, dest_align, scalar, layout.size, layout.align, signed) } Value::ScalarPair(a_val, b_val) => { trace!("write_value_to_ptr valpair: {:#?}", layout); @@ -1270,12 +1270,13 @@ pub fn write_value_to_ptr( _ => bug!("write_value_to_ptr: invalid ScalarPair layout: {:#?}", layout) }; let (a_size, b_size) = (a.size(&self), b.size(&self)); + let (a_align, b_align) = (a.align(&self), b.align(&self)); let a_ptr = dest; - let b_offset = a_size.abi_align(b.align(&self)); + let b_offset = a_size.abi_align(b_align); let b_ptr = dest.ptr_offset(b_offset, &self)?.into(); // TODO: What about signedess? - self.memory.write_scalar(a_ptr, dest_align, a_val, a_size, false)?; - self.memory.write_scalar(b_ptr, dest_align, b_val, b_size, false) + self.memory.write_scalar(a_ptr, dest_align, a_val, a_size, a_align, false)?; + self.memory.write_scalar(b_ptr, dest_align, b_val, b_size, b_align, false) } } } @@ -1290,7 +1291,7 @@ pub fn read_value(&self, ptr: Scalar, align: Align, ty: Ty<'tcx>) -> EvalResult< fn validate_scalar( &self, - value: Scalar, + value: ScalarMaybeUndef, size: Size, scalar: &layout::Scalar, path: &str, @@ -1299,6 +1300,11 @@ fn validate_scalar( trace!("validate scalar: {:#?}, {:#?}, {:#?}, {}", value, size, scalar, ty); let (lo, hi) = scalar.valid_range.clone().into_inner(); + let value = match value { + ScalarMaybeUndef::Scalar(scalar) => scalar, + ScalarMaybeUndef::Undef => return validation_failure!("undefined bytes", path), + }; + let bits = match value { Scalar::Bits { bits, size: value_size } => { assert_eq!(value_size as u64, size.bytes()); @@ -1351,13 +1357,21 @@ fn validate_scalar( if in_range(0..=hi) || in_range(lo..=u128::max_value()) { Ok(()) } else { - validation_failure!("undefined bytes", path) + validation_failure!( + bits, + path, + format!("something in the range {:?} or {:?}", ..=hi, lo..) + ) } } else { if in_range(scalar.valid_range.clone()) { Ok(()) } else { - validation_failure!("undefined bytes", path) + validation_failure!( + bits, + path, + format!("something in the range {:?}", scalar.valid_range) + ) } } } @@ -1387,10 +1401,10 @@ pub fn validate_ptr_target( mir::Field::new(0), layout, )?; - let tag_value = self.value_to_scalar(ValTy { - value: tag_value, - ty: tag_layout.ty, - })?; + let tag_value = match self.follow_by_ref_value(tag_value, tag_layout.ty)? { + Value::Scalar(val) => val, + _ => bug!("tag must be scalar"), + }; let path = format!("{}.TAG", path); self.validate_scalar(tag_value, size, tag, &path, tag_layout.ty)?; let variant_index = self.read_discriminant_as_variant_index( @@ -1413,11 +1427,11 @@ pub fn validate_ptr_target( // expectation. layout::Abi::Scalar(ref scalar) => { let size = scalar.value.size(self); - let value = self.memory.read_scalar(ptr, ptr_align, size)?.unwrap_or_err()?; + let value = self.memory.read_scalar(ptr, ptr_align, size)?; self.validate_scalar(value, size, scalar, &path, layout.ty)?; if scalar.value == Primitive::Pointer { // ignore integer pointers, we can't reason about the final hardware - if let Scalar::Ptr(ptr) = value { + if let Scalar::Ptr(ptr) = value.unwrap_or_err()? { let alloc_kind = self.tcx.alloc_map.lock().get(ptr.alloc_id); if let Some(AllocType::Static(did)) = alloc_kind { // statics from other crates are already checked diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index f120e0f7338..e251d7ec2bb 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -789,7 +789,15 @@ pub fn read_ptr_sized(&self, ptr: Pointer, ptr_align: Align) -> EvalResult<'tcx, self.read_scalar(ptr, ptr_align, self.pointer_size()) } - pub fn write_scalar(&mut self, ptr: Scalar, ptr_align: Align, val: ScalarMaybeUndef, type_size: Size, signed: bool) -> EvalResult<'tcx> { + pub fn write_scalar( + &mut self, + ptr: Scalar, + ptr_align: Align, + val: ScalarMaybeUndef, + type_size: Size, + type_align: Align, + signed: bool, + ) -> EvalResult<'tcx> { let endianness = self.endianness(); let val = match val { @@ -818,8 +826,7 @@ pub fn write_scalar(&mut self, ptr: Scalar, ptr_align: Align, val: ScalarMaybeUn let ptr = ptr.to_ptr()?; { - let align = self.int_align(type_size); - let dst = self.get_bytes_mut(ptr, type_size, ptr_align.min(align))?; + let dst = self.get_bytes_mut(ptr, type_size, ptr_align.min(type_align))?; if signed { write_target_int(endianness, dst, bytes as i128).unwrap(); } else { @@ -843,7 +850,7 @@ pub fn write_scalar(&mut self, ptr: Scalar, ptr_align: Align, val: ScalarMaybeUn pub fn write_ptr_sized_unsigned(&mut self, ptr: Pointer, ptr_align: Align, val: ScalarMaybeUndef) -> EvalResult<'tcx> { let ptr_size = self.pointer_size(); - self.write_scalar(ptr.into(), ptr_align, val, ptr_size, false) + self.write_scalar(ptr.into(), ptr_align, val, ptr_size, ptr_align, false) } fn int_align(&self, size: Size) -> Align { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 006343424ef..91c25192306 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -62,13 +62,13 @@ pub fn to_ptr_align(self) -> (ScalarMaybeUndef, Align) { let (ptr, align, _extra) = self.to_ptr_align_extra(); (ptr, align) } -/* + pub fn to_ptr(self) -> EvalResult<'tcx, Pointer> { // At this point, we forget about the alignment information -- the place has been turned into a reference, // and no matter where it came from, it now must be aligned. - self.to_ptr_align().0.to_ptr() + self.to_ptr_align().0.unwrap_or_err()?.to_ptr() } -*/ + pub(super) fn elem_ty_and_len( self, ty: Ty<'tcx>,