提交 996a4255 编写于 作者: R Ralf Jung

the visitor can already load the value for visit_primitive

上级 c2677211
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
}; };
use super::{ use super::{
OpTy, MPlaceTy, Machine, EvalContext, ValueVisitor OpTy, MPlaceTy, ImmTy, Machine, EvalContext, ValueVisitor
}; };
macro_rules! validation_failure { macro_rules! validation_failure {
...@@ -213,7 +213,7 @@ fn visit_field( ...@@ -213,7 +213,7 @@ fn visit_field(
fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx> fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
{ {
trace!("visit_value: {:?}, {:?}", *op, op.layout); trace!("visit_value: {:?}, {:?}", *op, op.layout);
// Translate enum discriminant errors to something nicer. // Translate some possible errors to something nicer.
match self.walk_value(op) { match self.walk_value(op) {
Ok(()) => Ok(()), Ok(()) => Ok(()),
Err(err) => match err.kind { Err(err) => match err.kind {
...@@ -221,16 +221,17 @@ fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx> ...@@ -221,16 +221,17 @@ fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
validation_failure!( validation_failure!(
val, self.path, "a valid enum discriminant" val, self.path, "a valid enum discriminant"
), ),
EvalErrorKind::ReadPointerAsBytes =>
validation_failure!(
"a pointer", self.path, "plain bytes"
),
_ => Err(err), _ => Err(err),
} }
} }
} }
fn visit_primitive(&mut self, op: OpTy<'tcx, M::PointerTag>) fn visit_primitive(&mut self, value: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
-> EvalResult<'tcx>
{ {
let value = try_validation!(self.ecx.read_immediate(op),
"uninitialized or unrepresentable data", self.path);
// Go over all the primitive types // Go over all the primitive types
let ty = value.layout.ty; let ty = value.layout.ty;
match ty.sty { match ty.sty {
...@@ -379,8 +380,7 @@ fn visit_primitive(&mut self, op: OpTy<'tcx, M::PointerTag>) ...@@ -379,8 +380,7 @@ fn visit_primitive(&mut self, op: OpTy<'tcx, M::PointerTag>)
Ok(()) Ok(())
} }
fn visit_uninhabited(&mut self, _op: OpTy<'tcx, M::PointerTag>) fn visit_uninhabited(&mut self) -> EvalResult<'tcx>
-> EvalResult<'tcx>
{ {
validation_failure!("a value of an uninhabited type", self.path) validation_failure!("a value of an uninhabited type", self.path)
} }
...@@ -390,8 +390,7 @@ fn visit_scalar( ...@@ -390,8 +390,7 @@ fn visit_scalar(
op: OpTy<'tcx, M::PointerTag>, op: OpTy<'tcx, M::PointerTag>,
layout: &layout::Scalar, layout: &layout::Scalar,
) -> EvalResult<'tcx> { ) -> EvalResult<'tcx> {
let value = try_validation!(self.ecx.read_scalar(op), let value = self.ecx.read_scalar(op)?;
"uninitialized or unrepresentable data", self.path);
// Determine the allowed range // Determine the allowed range
let (lo, hi) = layout.valid_range.clone().into_inner(); let (lo, hi) = layout.valid_range.clone().into_inner();
// `max_hi` is as big as the size fits // `max_hi` is as big as the size fits
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
}; };
use super::{ use super::{
Machine, EvalContext, MPlaceTy, PlaceTy, OpTy, Machine, EvalContext, MPlaceTy, PlaceTy, OpTy, ImmTy,
}; };
// A thing that we can project into, and that has a layout. // A thing that we can project into, and that has a layout.
...@@ -205,9 +205,11 @@ fn visit_field( ...@@ -205,9 +205,11 @@ fn visit_field(
/// Called whenever we reach a value with uninhabited layout. /// Called whenever we reach a value with uninhabited layout.
/// Recursing to fields will continue after this! /// Recursing to fields will continue after this!
#[inline(always)] #[inline(always)]
fn visit_uninhabited(&mut self, _v: Self::V) -> EvalResult<'tcx> fn visit_uninhabited(&mut self) -> EvalResult<'tcx>
{ Ok(()) } { Ok(()) }
/// Called whenever we reach a value with scalar layout. /// Called whenever we reach a value with scalar layout.
/// We do NOT provide a `ScalarMaybeUndef` here to avoid accessing memory
/// if the visitor is not even interested in scalars.
/// Recursing to fields will continue after this! /// Recursing to fields will continue after this!
#[inline(always)] #[inline(always)]
fn visit_scalar(&mut self, _v: Self::V, _layout: &layout::Scalar) -> EvalResult<'tcx> fn visit_scalar(&mut self, _v: Self::V, _layout: &layout::Scalar) -> EvalResult<'tcx>
...@@ -215,7 +217,7 @@ fn visit_scalar(&mut self, _v: Self::V, _layout: &layout::Scalar) -> EvalResult< ...@@ -215,7 +217,7 @@ fn visit_scalar(&mut self, _v: Self::V, _layout: &layout::Scalar) -> EvalResult<
/// Called whenever we reach a value of primitive type. There can be no recursion /// Called whenever we reach a value of primitive type. There can be no recursion
/// below such a value. /// below such a value.
#[inline(always)] #[inline(always)]
fn visit_primitive(&mut self, _v: Self::V) -> EvalResult<'tcx> fn visit_primitive(&mut self, _val: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
{ Ok(()) } { Ok(()) }
// Default recursors. Not meant to be overloaded. // Default recursors. Not meant to be overloaded.
...@@ -275,7 +277,7 @@ fn walk_value(&mut self, v: Self::V) -> EvalResult<'tcx> ...@@ -275,7 +277,7 @@ fn walk_value(&mut self, v: Self::V) -> EvalResult<'tcx>
// MyNewtype and then the scalar in there). // MyNewtype and then the scalar in there).
match v.layout().abi { match v.layout().abi {
layout::Abi::Uninhabited => { layout::Abi::Uninhabited => {
self.visit_uninhabited(v)?; self.visit_uninhabited()?;
} }
layout::Abi::Scalar(ref layout) => { layout::Abi::Scalar(ref layout) => {
self.visit_scalar(v, layout)?; self.visit_scalar(v, layout)?;
...@@ -295,7 +297,9 @@ fn walk_value(&mut self, v: Self::V) -> EvalResult<'tcx> ...@@ -295,7 +297,9 @@ fn walk_value(&mut self, v: Self::V) -> EvalResult<'tcx>
_ => v.layout().ty.builtin_deref(true).is_some(), _ => v.layout().ty.builtin_deref(true).is_some(),
}; };
if primitive { if primitive {
return self.visit_primitive(v); let op = v.to_op(self.ecx())?;
let val = self.ecx().read_immediate(op)?;
return self.visit_primitive(val);
} }
// Proceed into the fields. // Proceed into the fields.
......
...@@ -26,7 +26,7 @@ error[E0080]: it is undefined behavior to use this value ...@@ -26,7 +26,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-ref.rs:25:1 --> $DIR/ub-ref.rs:25:1
| |
LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a raw memory access tried to access part of a pointer value as raw bytes | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<deref>, but expected plain bytes
| |
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册