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]]
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"
+
[dependencies]
byteorder = "0.4.2"
+
+[dev-dependencies]
+compiletest_rs = "0.1.1"
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();
--- /dev/null
+#![feature(custom_attribute)]
+#![allow(dead_code, unused_attributes)]
+
+#[miri_run]
+fn overwriting_part_of_relocation_makes_the_rest_undefined() -> i32 {
+ let mut p = &42;
+ unsafe {
+ let ptr: *mut _ = &mut p;
+ *(ptr as *mut u32) = 123;
+ }
+ *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 //~ 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 } //~ 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 //~ 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) } //~ ERROR: pointer offset outside bounds of allocation
+}
+
+#[miri_run]
+fn dangling_pointer_deref() -> i32 {
+ let p = {
+ let b = Box::new(42);
+ &*b as *const i32
+ };
+ unsafe { *p } //~ ERROR: dangling pointer was dereferenced
+}
+
+fn main() {}
+++ /dev/null
-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);
- }
- }
-}
--- /dev/null
+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");
+}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
fn array_repeat() -> [u8; 8] {
[42; 8]
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
_ => 0,
}
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
_ => false,
}
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
fn test_size_of() -> usize {
::std::mem::size_of::<Option<i32>>()
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
// }
// y
// }
+
+fn main() {}
+++ /dev/null
-#![crate_type = "lib"]
-#![feature(custom_attribute)]
-#![allow(dead_code, unused_attributes)]
-
-#[miri_run]
-fn overwriting_part_of_relocation_makes_the_rest_undefined() -> i32 {
- let mut p = &42;
- unsafe {
- let ptr: *mut _ = &mut p;
- *(ptr as *mut u32) = 123;
- }
- *p
-}
-
-#[miri_run]
-fn pointers_to_different_allocations_are_unorderable() -> bool {
- let x: *const u8 = &1;
- let y: *const u8 = &2;
- x < y
-}
-
-#[miri_run]
-fn invalid_bool() -> u8 {
- let b = unsafe { std::mem::transmute::<u8, bool>(2) };
- if b { 1 } else { 2 }
-}
-
-#[miri_run]
-fn undefined_byte_read() -> u8 {
- let v: Vec<u8> = Vec::with_capacity(10);
- let undef = unsafe { *v.get_unchecked(5) };
- undef + 1
-}
-
-#[miri_run]
-fn out_of_bounds_read() -> u8 {
- let v: Vec<u8> = vec![1, 2];
- unsafe { *v.get_unchecked(5) }
-}
-
-#[miri_run]
-fn dangling_pointer_deref() -> i32 {
- let p = {
- let b = Box::new(42);
- &*b as *const i32
- };
- unsafe { *p }
-}
-#![crate_type = "lib"]
#![feature(custom_attribute, box_syntax)]
#![allow(dead_code, unused_attributes)]
fn make_box_syntax() -> Box<(i16, i16)> {
box (1, 2)
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
_ => 5,
}
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
}
sum
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
let b = Box::new(42);
&*b as *const i32
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
p.x += 5;
(p.x, p.y)
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute, specialization)]
#![allow(dead_code, unused_attributes)]
fn specialization() -> (bool, bool) {
(i32::is_unit(), <()>::is_unit())
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute, box_syntax)]
#![allow(dead_code, unused_attributes)]
fn true_assert() {
assert_eq!(1, 1);
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
fn hello_bytes_fat() -> &'static [u8] {
b"Hello, world!"
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
fn two_nones() -> (Option<i16>, Option<i16>) {
(None, None)
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
let x = ();
x
}
+
+fn main() {}
-#![crate_type = "lib"]
#![feature(custom_attribute)]
#![allow(dead_code, unused_attributes)]
v.push(5);
v
}
+
+fn main() {}