Merge branch 'master' into tests

This commit is contained in:
Ralf Jung 2017-09-16 12:55:49 +02:00 committed by GitHub
commit e7b0637e68
9 changed files with 49 additions and 8 deletions

View file

@ -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)

View file

@ -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,

View file

@ -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) };

View file

@ -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!() }
}

View file

@ -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' => {},
_ => {},
}

View file

@ -1,3 +1,6 @@
// This should fail even without validation
// compile-flags: -Zmir-emit-validate=0
#![allow(dead_code, unused_variables)]
#[repr(packed)]

View file

@ -1,3 +1,5 @@
// This should fail even without validation
// compile-flags: -Zmir-emit-validate=0
#![feature(i128_type)]
fn main() {

View 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();
}

View file

@ -1,3 +1,6 @@
// Moving around undef is not allowed by validation
// compile-flags: -Zmir-emit-validate=0
struct Foo {
_inner: i32,
}