Merge branch 'master' into tests
This commit is contained in:
commit
e7b0637e68
9 changed files with 49 additions and 8 deletions
|
|
@ -1483,6 +1483,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||
Value::ByRef { .. } => bug!("follow_by_ref_value can't result in `ByRef`"),
|
||||
|
||||
Value::ByVal(primval) => {
|
||||
// TODO: Do we really want insta-UB here?
|
||||
self.ensure_valid_value(primval, ty)?;
|
||||
Ok(primval)
|
||||
}
|
||||
|
|
@ -1817,6 +1818,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||
let val = match val {
|
||||
PrimVal::Bytes(0) => false,
|
||||
PrimVal::Bytes(1) => true,
|
||||
// TODO: This seems a little overeager, should reading at bool type already be UB?
|
||||
_ => return err!(InvalidBool),
|
||||
};
|
||||
PrimVal::from_bool(val)
|
||||
|
|
|
|||
|
|
@ -492,12 +492,22 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||
let res = do catch {
|
||||
match query.ty.sty {
|
||||
TyInt(_) | TyUint(_) | TyRawPtr(_) => {
|
||||
// TODO: Make sure these are not undef.
|
||||
// We could do a bounds-check and other sanity checks on the lvalue, but it would be a bug in miri for this to ever fail.
|
||||
if mode.acquiring() {
|
||||
// Make sure we can read this.
|
||||
let val = self.read_lvalue(query.lval.1)?;
|
||||
self.follow_by_ref_value(val, query.ty)?;
|
||||
// FIXME: It would be great to rule out Undef here, but that doesn't actually work.
|
||||
// Passing around undef data is a thing that e.g. Vec::extend_with does.
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
TyBool | TyFloat(_) | TyChar | TyStr => {
|
||||
// TODO: Check if these are valid bool/float/codepoint/UTF-8, respectively (and in particular, not undef).
|
||||
TyBool | TyFloat(_) | TyChar => {
|
||||
if mode.acquiring() {
|
||||
let val = self.read_lvalue(query.lval.1)?;
|
||||
let val = self.value_to_primval(ValTy { value: val, ty: query.ty })?;
|
||||
val.to_bytes()?;
|
||||
// TODO: Check if these are valid bool/float/codepoint/UTF-8
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
TyNever => err!(ValidationFailure(format!("The empty type is never valid."))),
|
||||
|
|
@ -542,6 +552,10 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||
}
|
||||
|
||||
// Compound types
|
||||
TyStr => {
|
||||
// TODO: Validate strings
|
||||
Ok(())
|
||||
}
|
||||
TySlice(elem_ty) => {
|
||||
let len = match query.lval.1 {
|
||||
Lvalue::Ptr { extra: LvalueExtra::Length(len), .. } => len,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// This should fail even without validation
|
||||
// compile-flags: -Zmir-emit-validate=0
|
||||
|
||||
fn main() {
|
||||
let v: Vec<u8> = Vec::with_capacity(10);
|
||||
let undef = unsafe { *v.get_unchecked(5) };
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
fn main() {
|
||||
let b = unsafe { std::mem::transmute::<u8, bool>(2) };
|
||||
if b { unreachable!() } else { unreachable!() } //~ ERROR: invalid boolean value read
|
||||
let b = unsafe { std::mem::transmute::<u8, bool>(2) }; //~ ERROR: invalid boolean value read
|
||||
if b { unreachable!() } else { unreachable!() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
fn main() {
|
||||
assert!(std::char::from_u32(-1_i32 as u32).is_none());
|
||||
match unsafe { std::mem::transmute::<i32, char>(-1) } {
|
||||
'a' => {}, //~ERROR tried to interpret an invalid 32-bit value as a char: 4294967295
|
||||
match unsafe { std::mem::transmute::<i32, char>(-1) } { //~ERROR tried to interpret an invalid 32-bit value as a char: 4294967295
|
||||
'a' => {},
|
||||
'b' => {},
|
||||
_ => {},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// This should fail even without validation
|
||||
// compile-flags: -Zmir-emit-validate=0
|
||||
|
||||
#![allow(dead_code, unused_variables)]
|
||||
|
||||
#[repr(packed)]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
// This should fail even without validation
|
||||
// compile-flags: -Zmir-emit-validate=0
|
||||
#![feature(i128_type)]
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
14
tests/compile-fail/validation_undef.rs
Normal file
14
tests/compile-fail/validation_undef.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#![allow(unused_variables)]
|
||||
// error-pattern: attempted to read undefined bytes
|
||||
|
||||
mod safe {
|
||||
use std::mem;
|
||||
|
||||
pub(crate) fn make_float() -> f32 {
|
||||
unsafe { mem::uninitialized() }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _x = safe::make_float();
|
||||
}
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
// Moving around undef is not allowed by validation
|
||||
// compile-flags: -Zmir-emit-validate=0
|
||||
|
||||
struct Foo {
|
||||
_inner: i32,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue