commit
ae41877b51
22 changed files with 81 additions and 62 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -3,6 +3,7 @@ name = "miri"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"compiletest_rs 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -10,3 +11,16 @@ name = "byteorder"
|
|||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "compiletest_rs"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
|
|
|
@ -12,3 +12,6 @@ name = "miri"
|
|||
|
||||
[dependencies]
|
||||
byteorder = "0.4.2"
|
||||
|
||||
[dev-dependencies]
|
||||
compiletest_rs = "0.1.1"
|
||||
|
|
|
@ -6,14 +6,13 @@ extern crate rustc_driver;
|
|||
|
||||
use miri::interpreter;
|
||||
use rustc::session::Session;
|
||||
use rustc_driver::{driver, CompilerCalls, Compilation};
|
||||
use rustc_driver::{driver, CompilerCalls};
|
||||
|
||||
struct MiriCompilerCalls;
|
||||
|
||||
impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
|
||||
fn build_controller(&mut self, _: &Session) -> driver::CompileController<'a> {
|
||||
let mut control = driver::CompileController::basic();
|
||||
control.after_analysis.stop = Compilation::Stop;
|
||||
|
||||
control.after_analysis.callback = Box::new(|state| {
|
||||
state.session.abort_if_errors();
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -9,33 +8,33 @@ fn overwriting_part_of_relocation_makes_the_rest_undefined() -> i32 {
|
|||
let ptr: *mut _ = &mut p;
|
||||
*(ptr as *mut u32) = 123;
|
||||
}
|
||||
*p
|
||||
*p //~ ERROR: attempted to read undefined bytes
|
||||
}
|
||||
|
||||
#[miri_run]
|
||||
fn pointers_to_different_allocations_are_unorderable() -> bool {
|
||||
let x: *const u8 = &1;
|
||||
let y: *const u8 = &2;
|
||||
x < y
|
||||
x < y //~ ERROR: attempted to do math or a comparison on pointers into different allocations
|
||||
}
|
||||
|
||||
#[miri_run]
|
||||
fn invalid_bool() -> u8 {
|
||||
let b = unsafe { std::mem::transmute::<u8, bool>(2) };
|
||||
if b { 1 } else { 2 }
|
||||
if b { 1 } else { 2 } //~ ERROR: invalid boolean value read
|
||||
}
|
||||
|
||||
#[miri_run]
|
||||
fn undefined_byte_read() -> u8 {
|
||||
let v: Vec<u8> = Vec::with_capacity(10);
|
||||
let undef = unsafe { *v.get_unchecked(5) };
|
||||
undef + 1
|
||||
undef + 1 //~ ERROR: attempted to read undefined bytes
|
||||
}
|
||||
|
||||
#[miri_run]
|
||||
fn out_of_bounds_read() -> u8 {
|
||||
let v: Vec<u8> = vec![1, 2];
|
||||
unsafe { *v.get_unchecked(5) }
|
||||
unsafe { *v.get_unchecked(5) } //~ ERROR: pointer offset outside bounds of allocation
|
||||
}
|
||||
|
||||
#[miri_run]
|
||||
|
@ -44,5 +43,7 @@ fn dangling_pointer_deref() -> i32 {
|
|||
let b = Box::new(42);
|
||||
&*b as *const i32
|
||||
};
|
||||
unsafe { *p }
|
||||
unsafe { *p } //~ ERROR: dangling pointer was dereferenced
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,37 +0,0 @@
|
|||
use std::{env, fs};
|
||||
use std::process::{Command, Output};
|
||||
|
||||
fn run_miri(file: &str, sysroot: &str) -> Output {
|
||||
Command::new("cargo")
|
||||
.args(&["run", "--", "--sysroot", sysroot, file])
|
||||
.output()
|
||||
.unwrap_or_else(|e| panic!("failed to execute process: {}", e))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_pass() {
|
||||
let sysroot = env::var("RUST_SYSROOT").expect("env variable `RUST_SYSROOT` not set");
|
||||
|
||||
let test_files = fs::read_dir("./tests/run-pass/")
|
||||
.expect("Can't read `run-pass` directory")
|
||||
.filter_map(|entry| entry.ok())
|
||||
.filter(|entry| {
|
||||
entry.clone()
|
||||
.file_type()
|
||||
.map(|x| x.is_file())
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.filter_map(|entry| entry.path().to_str().map(|x| x.to_string()));
|
||||
|
||||
for file in test_files {
|
||||
println!("{}: compile test running", file);
|
||||
|
||||
let test_run = run_miri(&file, &sysroot);
|
||||
|
||||
if test_run.status.code().unwrap_or(-1) != 0 {
|
||||
println!("{}: error {:?}", file, test_run);
|
||||
} else {
|
||||
println!("{}: ok", file);
|
||||
}
|
||||
}
|
||||
}
|
23
tests/compiletest.rs
Normal file
23
tests/compiletest.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
extern crate compiletest_rs as compiletest;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn run_mode(mode: &'static str) {
|
||||
let mut config = compiletest::default_config();
|
||||
config.rustc_path = "target/debug/miri".into();
|
||||
let path = std::env::var("RUST_SYSROOT").expect("env variable `RUST_SYSROOT` not set");
|
||||
config.target_rustcflags = Some(format!("--sysroot {}", path));
|
||||
config.host_rustcflags = Some(format!("--sysroot {}", path));
|
||||
let cfg_mode = mode.parse().ok().expect("Invalid mode");
|
||||
|
||||
config.mode = cfg_mode;
|
||||
config.src_base = PathBuf::from(format!("tests/{}", mode));
|
||||
|
||||
compiletest::run_tests(&config);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compile_test() {
|
||||
run_mode("compile-fail");
|
||||
run_mode("run-pass");
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -33,3 +32,5 @@ fn index() -> i32 {
|
|||
fn array_repeat() -> [u8; 8] {
|
||||
[42; 8]
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -27,3 +26,5 @@ fn match_bool() -> i16 {
|
|||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -20,3 +19,5 @@ fn unsafe_match() -> bool {
|
|||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -39,3 +38,5 @@ fn cross_crate_fn_call() -> i64 {
|
|||
fn test_size_of() -> usize {
|
||||
::std::mem::size_of::<Option<i32>>()
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -37,3 +36,5 @@ fn crazy_closure() -> (i32, i32, i32) {
|
|||
// }
|
||||
// y
|
||||
// }
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute, box_syntax)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -11,3 +10,5 @@ fn make_box() -> Box<(i16, i16)> {
|
|||
fn make_box_syntax() -> Box<(i16, i16)> {
|
||||
box (1, 2)
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -53,3 +52,5 @@ fn match_int_range() -> i64 {
|
|||
_ => 5,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -34,3 +33,5 @@ fn for_loop() -> usize {
|
|||
}
|
||||
sum
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -58,3 +57,5 @@ fn dangling_pointer() -> *const i32 {
|
|||
let b = Box::new(42);
|
||||
&*b as *const i32
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -30,3 +29,5 @@ fn field_access() -> (i8, i8) {
|
|||
p.x += 5;
|
||||
(p.x, p.y)
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute, specialization)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -18,3 +17,5 @@ impl IsUnit for () {
|
|||
fn specialization() -> (bool, bool) {
|
||||
(i32::is_unit(), <()>::is_unit())
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute, box_syntax)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -44,3 +43,5 @@ fn rc_reference_cycle() -> Loop {
|
|||
fn true_assert() {
|
||||
assert_eq!(1, 1);
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -21,3 +20,5 @@ fn hello_bytes() -> &'static [u8; 13] {
|
|||
fn hello_bytes_fat() -> &'static [u8] {
|
||||
b"Hello, world!"
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -53,3 +52,5 @@ fn match_opt_some() -> i8 {
|
|||
fn two_nones() -> (Option<i16>, Option<i16>) {
|
||||
(None, None)
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -10,3 +9,5 @@ fn unit_var() {
|
|||
let x = ();
|
||||
x
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![crate_type = "lib"]
|
||||
#![feature(custom_attribute)]
|
||||
#![allow(dead_code, unused_attributes)]
|
||||
|
||||
|
@ -36,3 +35,5 @@ fn vec_reallocate() -> Vec<u8> {
|
|||
v.push(5);
|
||||
v
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue