Skip to content

Commit 25f5afa

Browse files
committed
the visitor can already load the value for visit_primitive
1 parent d0e8a92 commit 25f5afa

File tree

3 files changed

+19
-16
lines changed

3 files changed

+19
-16
lines changed

src/librustc_mir/interpret/validity.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc::mir::interpret::{
2020
};
2121

2222
use super::{
23-
OpTy, MPlaceTy, Machine, EvalContext, ValueVisitor
23+
OpTy, MPlaceTy, ValTy, Machine, EvalContext, ValueVisitor
2424
};
2525

2626
macro_rules! validation_failure {
@@ -213,24 +213,25 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
213213
fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
214214
{
215215
trace!("visit_value: {:?}, {:?}", *op, op.layout);
216-
// Translate enum discriminant errors to something nicer.
216+
// Translate some possible errors to something nicer.
217217
match self.walk_value(op) {
218218
Ok(()) => Ok(()),
219219
Err(err) => match err.kind {
220220
EvalErrorKind::InvalidDiscriminant(val) =>
221221
validation_failure!(
222222
val, self.path, "a valid enum discriminant"
223223
),
224+
EvalErrorKind::ReadPointerAsBytes =>
225+
validation_failure!(
226+
"a pointer", self.path, "plain bytes"
227+
),
224228
_ => Err(err),
225229
}
226230
}
227231
}
228232

229-
fn visit_primitive(&mut self, op: OpTy<'tcx, M::PointerTag>)
230-
-> EvalResult<'tcx>
233+
fn visit_primitive(&mut self, value: ValTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
231234
{
232-
let value = try_validation!(self.ecx.read_value(op),
233-
"uninitialized or unrepresentable data", self.path);
234235
// Go over all the primitive types
235236
let ty = value.layout.ty;
236237
match ty.sty {
@@ -379,8 +380,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
379380
Ok(())
380381
}
381382

382-
fn visit_uninhabited(&mut self, _op: OpTy<'tcx, M::PointerTag>)
383-
-> EvalResult<'tcx>
383+
fn visit_uninhabited(&mut self) -> EvalResult<'tcx>
384384
{
385385
validation_failure!("a value of an uninhabited type", self.path)
386386
}
@@ -390,8 +390,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
390390
op: OpTy<'tcx, M::PointerTag>,
391391
layout: &layout::Scalar,
392392
) -> EvalResult<'tcx> {
393-
let value = try_validation!(self.ecx.read_scalar(op),
394-
"uninitialized or unrepresentable data", self.path);
393+
let value = self.ecx.read_scalar(op)?;
395394
// Determine the allowed range
396395
let (lo, hi) = layout.valid_range.clone().into_inner();
397396
// `max_hi` is as big as the size fits

src/librustc_mir/interpret/visitor.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc::mir::interpret::{
88
};
99

1010
use super::{
11-
Machine, EvalContext, MPlaceTy, PlaceTy, OpTy,
11+
Machine, EvalContext, MPlaceTy, PlaceTy, OpTy, ValTy,
1212
};
1313

1414
// A thing that we can project into, and that has a layout.
@@ -205,17 +205,19 @@ pub trait ValueVisitor<'a, 'mir, 'tcx: 'mir+'a, M: Machine<'a, 'mir, 'tcx>>: Siz
205205
/// Called whenever we reach a value with uninhabited layout.
206206
/// Recursing to fields will continue after this!
207207
#[inline(always)]
208-
fn visit_uninhabited(&mut self, _v: Self::V) -> EvalResult<'tcx>
208+
fn visit_uninhabited(&mut self) -> EvalResult<'tcx>
209209
{ Ok(()) }
210210
/// Called whenever we reach a value with scalar layout.
211+
/// We do NOT provide a `ScalarMaybeUndef` here to avoid accessing memory
212+
/// if the visitor is not even interested in scalars.
211213
/// Recursing to fields will continue after this!
212214
#[inline(always)]
213215
fn visit_scalar(&mut self, _v: Self::V, _layout: &layout::Scalar) -> EvalResult<'tcx>
214216
{ Ok(()) }
215217
/// Called whenever we reach a value of primitive type. There can be no recursion
216218
/// below such a value.
217219
#[inline(always)]
218-
fn visit_primitive(&mut self, _v: Self::V) -> EvalResult<'tcx>
220+
fn visit_primitive(&mut self, _val: ValTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
219221
{ Ok(()) }
220222

221223
// Default recursors. Not meant to be overloaded.
@@ -275,7 +277,7 @@ pub trait ValueVisitor<'a, 'mir, 'tcx: 'mir+'a, M: Machine<'a, 'mir, 'tcx>>: Siz
275277
// MyNewtype and then the scalar in there).
276278
match v.layout().abi {
277279
layout::Abi::Uninhabited => {
278-
self.visit_uninhabited(v)?;
280+
self.visit_uninhabited()?;
279281
}
280282
layout::Abi::Scalar(ref layout) => {
281283
self.visit_scalar(v, layout)?;
@@ -295,7 +297,9 @@ pub trait ValueVisitor<'a, 'mir, 'tcx: 'mir+'a, M: Machine<'a, 'mir, 'tcx>>: Siz
295297
_ => v.layout().ty.builtin_deref(true).is_some(),
296298
};
297299
if primitive {
298-
return self.visit_primitive(v);
300+
let op = v.to_op(self.ecx())?;
301+
let val = self.ecx().read_value(op)?;
302+
return self.visit_primitive(val);
299303
}
300304

301305
// Proceed into the fields.

src/test/ui/consts/const-eval/ub-ref.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ error[E0080]: it is undefined behavior to use this value
2626
--> $DIR/ub-ref.rs:25:1
2727
|
2828
LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
29-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a raw memory access tried to access part of a pointer value as raw bytes
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<deref>, but expected plain bytes
3030
|
3131
= 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
3232

0 commit comments

Comments
 (0)