Skip to content

Commit 10244b5

Browse files
authored
Merge pull request #477 from RalfJung/miri-validate
Validate more things
2 parents 26f9d61 + c9cf034 commit 10244b5

24 files changed

+67
-56
lines changed

src/lib.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,26 @@ impl<'a, 'mir, 'tcx> Machine<'a, 'mir, 'tcx> for Evaluator<'tcx> {
255255

256256
const STATIC_KIND: Option<MiriMemoryKind> = Some(MiriMemoryKind::MutStatic);
257257

258-
#[inline(always)]
259258
fn enforce_validity(ecx: &EvalContext<'a, 'mir, 'tcx, Self>) -> bool {
260-
ecx.machine.validate
259+
if !ecx.machine.validate {
260+
return false;
261+
}
262+
263+
// Some functions are whitelisted until we figure out how to fix them.
264+
// We walk up the stack a few frames to also cover their callees.
265+
const WHITELIST: &[&str] = &[
266+
// Uses mem::uninitialized
267+
"std::ptr::read",
268+
];
269+
for frame in ecx.stack().iter()
270+
.rev().take(3)
271+
{
272+
let name = frame.instance.to_string();
273+
if WHITELIST.iter().any(|white| name.starts_with(white)) {
274+
return false;
275+
}
276+
}
277+
true
261278
}
262279

263280
/// Returns Ok() when the function was handled, fail otherwise

tests/compile-fail/cast_box_int_to_fn_ptr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Validation makes this fail in the wrong place
2-
// compile-flags: -Zmir-emit-validate=0
2+
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
33

44
fn main() {
55
let b = Box::new(42);

tests/compile-fail/cast_int_to_fn_ptr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Validation makes this fail in the wrong place
2-
// compile-flags: -Zmir-emit-validate=0
2+
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
33

44
fn main() {
55
let g = unsafe {

tests/compile-fail/execute_memory.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Validation makes this fail in the wrong place
2-
// compile-flags: -Zmir-emit-validate=0
2+
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
33

44
#![feature(box_syntax)]
55

tests/compile-fail/fn_ptr_offset.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Validation makes this fail in the wrong place
2-
// compile-flags: -Zmir-emit-validate=0
2+
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
33

44
use std::mem;
55

tests/compile-fail/invalid_bool.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
//ignore-test FIXME: do some basic validation of invariants for all values in flight
2-
//This does currently not get caught becuase it compiles to SwitchInt, which
3-
//has no knowledge about data invariants.
4-
51
fn main() {
6-
let b = unsafe { std::mem::transmute::<u8, bool>(2) };
7-
if b { unreachable!() } else { unreachable!() } //~ ERROR constant evaluation error
8-
//~^ NOTE invalid boolean value read
2+
let _b = unsafe { std::mem::transmute::<u8, bool>(2) }; //~ ERROR encountered 2, but expected something in the range 0..=1
93
}

tests/compile-fail/invalid_bool2.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Validation makes this fail in the wrong place
2+
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
3+
14
fn main() {
25
let b = unsafe { std::mem::transmute::<u8, bool>(2) };
36
let _x = b == true; //~ ERROR invalid boolean value read

tests/compile-fail/invalid_char.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() {
2+
assert!(std::char::from_u32(-1_i32 as u32).is_none());
3+
let _ = match unsafe { std::mem::transmute::<i32, char>(-1) } { //~ ERROR encountered 4294967295, but expected something in the range 0..=1114111
4+
'a' => {true},
5+
'b' => {false},
6+
_ => {true},
7+
};
8+
}

tests/compile-fail/match_char2.rs renamed to tests/compile-fail/invalid_char2.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Validation makes this fail in the wrong place
2+
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
3+
14
fn main() {
25
assert!(std::char::from_u32(-1_i32 as u32).is_none());
36
let c = unsafe { std::mem::transmute::<i32, char>(-1) };
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,8 @@
1-
// Validation makes this fail in the wrong place
2-
// compile-flags: -Zmir-emit-validate=0
3-
41
#[repr(C)]
52
pub enum Foo {
63
A, B, C, D
74
}
85

96
fn main() {
10-
let f = unsafe { std::mem::transmute::<i32, Foo>(42) };
11-
match f {
12-
Foo::A => {}, //~ ERROR invalid enum discriminant
13-
Foo::B => {},
14-
Foo::C => {},
15-
Foo::D => {},
16-
}
7+
let _f = unsafe { std::mem::transmute::<i32, Foo>(42) }; //~ ERROR encountered invalid enum discriminant 42
178
}

tests/compile-fail/invalid_enum_discriminant2.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Validation makes this fail in the wrong place
2-
// compile-flags: -Zmir-emit-validate=0
2+
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
33

44
// error-pattern: invalid enum discriminant
55

tests/compile-fail/match_char.rs

-13
This file was deleted.

tests/compile-fail/never_say_never.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// This should fail even without validation
2-
// compile-flags: -Zmir-emit-validate=0
2+
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
33

44
#![feature(never_type)]
55
#![allow(unreachable_code)]

tests/compile-fail/never_transmute_humans.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// This should fail even without validation
2-
// compile-flags: -Zmir-emit-validate=0
2+
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
33

44
#![feature(never_type)]
55
#![allow(unreachable_code)]

tests/compile-fail/never_transmute_void.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// This should fail even without validation
2-
// compile-flags: -Zmir-emit-validate=0
2+
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
33

44
#![feature(never_type)]
55
#![allow(unreachable_code)]

tests/compile-fail/reference_to_packed.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// This should fail even without validation
2-
// compile-flags: -Zmir-emit-validate=0
2+
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
33

44
#![allow(dead_code, unused_variables)]
55

tests/compile-fail/storage_dead_dangling.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// This should fail even without validation
2+
// compile-flags: -Zmir-emit-validate=0 -Zmiri-disable-validation
3+
14
static mut LEAK: usize = 0;
25

36
fn fill(v: &mut i32) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fn main() {
2+
// Cast a function pointer such that on a call, the argument gets transmuted
3+
// from raw ptr to reference. This is ABI-compatible, so it's not the call that
4+
// should fail, but validation should.
5+
fn f(_x: &i32) { }
6+
7+
let g: fn(*const i32) = unsafe { std::mem::transmute(f as fn(&i32)) };
8+
9+
g(0usize as *const i32) //~ ERROR encountered 0, but expected something greater or equal to 1
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fn main() {
2+
// Cast a function pointer such that when returning, the return value gets transmuted
3+
// from raw ptr to reference. This is ABI-compatible, so it's not the call that
4+
// should fail, but validation should.
5+
fn f() -> *const i32 { 0usize as *const i32 }
6+
7+
let g: fn() -> &'static i32 = unsafe { std::mem::transmute(f as fn() -> *const i32) };
8+
9+
let _x = g(); //~ ERROR encountered 0, but expected something greater or equal to 1
10+
}

tests/compiletest.rs

-3
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ fn compile_fail(sysroot: &Path, path: &str, target: &str, host: &str, need_fullm
6464
flags.push("-Dwarnings -Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs
6565
config.src_base = PathBuf::from(path.to_string());
6666
flags.push("-Zmir-emit-validate=1".to_owned());
67-
flags.push("-Zmiri-disable-validation".to_owned());
6867
config.target_rustcflags = Some(flags.join(" "));
6968
config.target = target.to_owned();
7069
config.host = host.to_owned();
@@ -103,8 +102,6 @@ fn miri_pass(sysroot: &Path, path: &str, target: &str, host: &str, need_fullmir:
103102
flags.push("-Dwarnings -Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs
104103
if have_fullmir() {
105104
flags.push("-Zmiri-start-fn".to_owned());
106-
// start-fn uses ptr::read, and so fails validation
107-
flags.push("-Zmiri-disable-validation".to_owned());
108105
}
109106
if opt {
110107
flags.push("-Zmir-opt-level=3".to_owned());

tests/run-pass/call_drop_through_owned_slice.rs

-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
// FIXME validation disabled because ptr::read uses mem::uninitialized
2-
// compile-flags: -Zmiri-disable-validation
3-
41
struct Bar;
52

63
static mut DROP_COUNT: usize = 0;

tests/run-pass/issue-29746.rs

-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// FIXME validation disabled because ptr::read uses mem::uninitialized
12-
// compile-flags: -Zmiri-disable-validation
13-
1411
// zip!(a1,a2,a3,a4) is equivalent to:
1512
// a1.zip(a2).zip(a3).zip(a4).map(|(((x1,x2),x3),x4)| (x1,x2,x3,x4))
1613
macro_rules! zip {

tests/run-pass/sendable-class.rs

-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// FIXME validation disabled because ptr::read uses mem::uninitialized
12-
// compile-flags: -Zmiri-disable-validation
13-
1411
// Test that a class with only sendable fields can be sent
1512

1613
use std::sync::mpsc::channel;

tests/run-pass/unique-send.rs

-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// FIXME validation disabled because ptr::read uses mem::uninitialized
12-
// compile-flags: -Zmiri-disable-validation
13-
1411
#![feature(box_syntax)]
1512

1613
use std::sync::mpsc::channel;

0 commit comments

Comments
 (0)