Auto merge of #2158 - rust-lang:gesundheit, r=RalfJung
Avoid error patterns matching themselves fixes #2156 fixes https://github.com/rust-lang/miri/issues/2155 this will be obsolete the moment I extract that data from json diagnostics instead of just regexing the stderr.
This commit is contained in:
commit
065ff89e33
18 changed files with 428 additions and 20 deletions
5
miri
5
miri
|
|
@ -133,8 +133,9 @@ test|test-debug|bless|bless-debug)
|
|||
;;
|
||||
esac
|
||||
# Then test, and let caller control flags.
|
||||
# Only in root project as `cargo-miri` has no tests.
|
||||
exec cargo test $CARGO_BUILD_FLAGS "$@"
|
||||
# Only in root project and ui_test as `cargo-miri` has no tests.
|
||||
cargo test $CARGO_BUILD_FLAGS "$@"
|
||||
cargo test $CARGO_BUILD_FLAGS --manifest-path ui_test/Cargo.toml "$@"
|
||||
;;
|
||||
run|run-debug)
|
||||
# Scan for "--target" to set the "MIRI_TEST_TARGET" env var so
|
||||
|
|
|
|||
|
|
@ -9,5 +9,5 @@ fn main() {
|
|||
let mut data = [0u16; 8];
|
||||
let ptr = (&mut data[0] as *mut u16 as *mut u8).wrapping_add(1) as *mut u16;
|
||||
// Even copying 0 elements to something unaligned should error
|
||||
unsafe { copy_nonoverlapping(&data[5], ptr, 0); } //~ ERROR accessing memory with alignment ALIGN, but alignment ALIGN is required
|
||||
unsafe { copy_nonoverlapping(&data[5], ptr, 0); } //~ ERROR accessing memory with alignment 1, but alignment 2 is required
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@ static X: usize = 5;
|
|||
#[allow(mutable_transmutes)]
|
||||
fn main() {
|
||||
let _x = unsafe {
|
||||
std::mem::transmute::<&usize, &mut usize>(&X) //~ ERROR writing to ALLOC which is read-only
|
||||
std::mem::transmute::<&usize, &mut usize>(&X) //~ ERROR writing to alloc1 which is read-only
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ fn main() {
|
|||
// Overwrite the data part of `ptr` so it points to `buf`.
|
||||
unsafe { (&mut ptr as *mut _ as *mut *const u8).write(&buf as *const _ as *const u8); }
|
||||
// Re-borrow that. This should be UB.
|
||||
let _ptr = &*ptr; //~ERROR alignment ALIGN is required
|
||||
let _ptr = &*ptr; //~ERROR alignment 256 is required
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,6 @@ fn main() {
|
|||
// Manually make sure the pointer is properly aligned.
|
||||
let base_addr_aligned = if base_addr % 2 == 0 { base_addr } else { base_addr+1 };
|
||||
let u16_ptr = base_addr_aligned as *mut u16;
|
||||
unsafe { *u16_ptr = 2; } //~ERROR memory with alignment ALIGN, but alignment ALIGN is required
|
||||
unsafe { *u16_ptr = 2; } //~ERROR memory with alignment 1, but alignment 2 is required
|
||||
println!("{:?}", x);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ fn main() {
|
|||
y: 99,
|
||||
};
|
||||
let p = &foo.x;
|
||||
let i = *p; //~ERROR alignment ALIGN is required
|
||||
let i = *p; //~ERROR alignment 4 is required
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,6 @@ fn main() {
|
|||
let x = [2u16, 3, 4]; // Make it big enough so we don't get an out-of-bounds error.
|
||||
let x = &x[0] as *const _ as *const u32;
|
||||
// This must fail because alignment is violated: the allocation's base is not sufficiently aligned.
|
||||
let _x = unsafe { *x }; //~ERROR memory with alignment ALIGN, but alignment ALIGN is required
|
||||
let _x = unsafe { *x }; //~ERROR memory with alignment 2, but alignment 4 is required
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,5 +8,5 @@ fn main() {
|
|||
let x = (x.as_ptr() as *const u8).wrapping_offset(3) as *const u32;
|
||||
// This must fail because alignment is violated: the offset is not sufficiently aligned.
|
||||
// Also make the offset not a power of 2, that used to ICE.
|
||||
let _x = unsafe { *x }; //~ERROR memory with alignment ALIGN, but alignment ALIGN is required
|
||||
let _x = unsafe { *x }; //~ERROR memory with alignment 1, but alignment 4 is required
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@ fn main() {
|
|||
let x = &x[0] as *const _ as *const u32;
|
||||
// This must fail because alignment is violated: the allocation's base is not sufficiently aligned.
|
||||
// The deref is UB even if we just put the result into a raw pointer.
|
||||
let _x = unsafe { ptr::addr_of!(*x) }; //~ ERROR memory with alignment ALIGN, but alignment ALIGN is required
|
||||
let _x = unsafe { ptr::addr_of!(*x) }; //~ ERROR memory with alignment 2, but alignment 4 is required
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,6 @@ fn main() {
|
|||
let x = i as u8;
|
||||
let x = &x as *const _ as *const [u32; 0];
|
||||
// This must fail because alignment is violated. Test specifically for loading ZST.
|
||||
let _x = unsafe { *x }; //~ERROR alignment ALIGN is required
|
||||
let _x = unsafe { *x }; //~ERROR alignment 4 is required
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@
|
|||
use std::mem;
|
||||
|
||||
fn main() {
|
||||
let _x: &i32 = unsafe { mem::transmute(16usize) }; //~ ERROR encountered a dangling reference (address $HEX is unallocated)
|
||||
let _x: &i32 = unsafe { mem::transmute(16usize) }; //~ ERROR encountered a dangling reference (address 0x10 is unallocated)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
fn main() {
|
||||
assert!(std::char::from_u32(-1_i32 as u32).is_none());
|
||||
let _val = match unsafe { std::mem::transmute::<i32, char>(-1) } { //~ ERROR encountered $HEX, but expected a valid unicode scalar value
|
||||
let _val = match unsafe { std::mem::transmute::<i32, char>(-1) } { //~ ERROR encountered 0xffffffff, but expected a valid unicode scalar value
|
||||
'a' => {true},
|
||||
'b' => {false},
|
||||
_ => {true},
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ fn run_tests(mode: Mode, path: &str, target: Option<String>) {
|
|||
(true, true) => panic!("cannot use MIRI_BLESS and MIRI_SKIP_UI_CHECKS at the same time"),
|
||||
};
|
||||
|
||||
let path_filter = std::env::args().skip(1).next();
|
||||
|
||||
let config = Config {
|
||||
args: flags,
|
||||
target,
|
||||
|
|
@ -54,6 +56,7 @@ fn run_tests(mode: Mode, path: &str, target: Option<String>) {
|
|||
stdout_filters: STDOUT.clone(),
|
||||
root_dir: PathBuf::from(path),
|
||||
mode,
|
||||
path_filter,
|
||||
program: miri_path(),
|
||||
output_conflict_handling,
|
||||
};
|
||||
|
|
|
|||
304
ui_test/Cargo.lock
generated
Normal file
304
ui_test/Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"lazy_static",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-queue",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f25d8400f4a7a5778f0e4e52384a48cbd9b5c495d110786187fc750075277a2"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "output_vt100"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c89f989ac94207d048d92db058e4f6ec7342b0971fc58d1271ca148b799b3563"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"ctor",
|
||||
"diff",
|
||||
"output_vt100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ui_test"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"colored",
|
||||
"crossbeam",
|
||||
"lazy_static",
|
||||
"pretty_assertions",
|
||||
"regex",
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
|
@ -2,11 +2,14 @@ use std::path::Path;
|
|||
|
||||
use regex::Regex;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
/// This crate supports various magic comments that get parsed as file-specific
|
||||
/// configuration values. This struct parses them all in one go and then they
|
||||
/// get processed by their respective use sites.
|
||||
#[derive(Default)]
|
||||
pub struct Comments {
|
||||
#[derive(Default, Debug)]
|
||||
pub(crate) struct Comments {
|
||||
/// List of revision names to execute. Can only be speicified once
|
||||
pub revisions: Option<Vec<String>>,
|
||||
/// Don't run this test if any of these filters apply
|
||||
|
|
@ -26,16 +29,23 @@ pub struct Comments {
|
|||
pub error_matches: Vec<ErrorMatch>,
|
||||
}
|
||||
|
||||
pub struct ErrorMatch {
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ErrorMatch {
|
||||
pub matched: String,
|
||||
pub revision: Option<String>,
|
||||
pub definition_line: usize,
|
||||
}
|
||||
|
||||
impl Comments {
|
||||
pub fn parse(path: &Path) -> Self {
|
||||
let mut this = Self::default();
|
||||
pub(crate) fn parse_file(path: &Path) -> Self {
|
||||
let content = std::fs::read_to_string(path).unwrap();
|
||||
Self::parse(path, &content)
|
||||
}
|
||||
|
||||
/// Parse comments in `content`.
|
||||
/// `path` is only used to emit diagnostics if parsing fails.
|
||||
pub(crate) fn parse(path: &Path, content: &str) -> Self {
|
||||
let mut this = Self::default();
|
||||
let error_pattern_regex =
|
||||
Regex::new(r"//(\[(?P<revision>[^\]]+)\])?~[|^]*\s*(ERROR|HELP|WARN)?:?(?P<text>.*)")
|
||||
.unwrap();
|
||||
|
|
|
|||
22
ui_test/src/comments/tests.rs
Normal file
22
ui_test/src/comments/tests.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
use std::path::Path;
|
||||
|
||||
use super::Comments;
|
||||
|
||||
#[test]
|
||||
fn parse_simple_comment() {
|
||||
let s = r"
|
||||
use std::mem;
|
||||
|
||||
fn main() {
|
||||
let _x: &i32 = unsafe { mem::transmute(16usize) }; //~ ERROR encountered a dangling reference (address $HEX is unallocated)
|
||||
}
|
||||
";
|
||||
let comments = Comments::parse(Path::new("<dummy>"), s);
|
||||
println!("parsed comments: {:#?}", comments);
|
||||
assert_eq!(comments.error_matches[0].definition_line, 4);
|
||||
assert_eq!(comments.error_matches[0].revision, None);
|
||||
assert_eq!(
|
||||
comments.error_matches[0].matched,
|
||||
"encountered a dangling reference (address $HEX is unallocated)"
|
||||
);
|
||||
}
|
||||
|
|
@ -12,6 +12,8 @@ use regex::Regex;
|
|||
use crate::comments::Comments;
|
||||
|
||||
mod comments;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Config {
|
||||
|
|
@ -28,6 +30,8 @@ pub struct Config {
|
|||
pub mode: Mode,
|
||||
pub program: PathBuf,
|
||||
pub output_conflict_handling: OutputConflictHandling,
|
||||
/// Only run tests with this string in their path/name
|
||||
pub path_filter: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -73,7 +77,18 @@ pub fn run_tests(config: Config) {
|
|||
if !path.extension().map(|ext| ext == "rs").unwrap_or(false) {
|
||||
continue;
|
||||
}
|
||||
let comments = Comments::parse(&path);
|
||||
if let Some(path_filter) = &config.path_filter {
|
||||
if !path.display().to_string().contains(path_filter) {
|
||||
ignored.fetch_add(1, Ordering::Relaxed);
|
||||
eprintln!(
|
||||
"{} .. {}",
|
||||
path.display(),
|
||||
"ignored (command line filter)".yellow()
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let comments = Comments::parse_file(&path);
|
||||
// Ignore file if only/ignore rules do (not) apply
|
||||
if ignore_file(&comments, &target) {
|
||||
ignored.fetch_add(1, Ordering::Relaxed);
|
||||
|
|
@ -129,7 +144,7 @@ pub fn run_tests(config: Config) {
|
|||
eprintln!("`{pattern}` {} in stderr output", "not found".red());
|
||||
eprintln!(
|
||||
"expected because of pattern here: {}:{definition_line}",
|
||||
path.display()
|
||||
path.display().to_string().bold()
|
||||
);
|
||||
dump_stderr = Some(stderr.clone())
|
||||
}
|
||||
|
|
@ -257,6 +272,9 @@ fn check_annotations(
|
|||
comments: &Comments,
|
||||
) {
|
||||
let unnormalized_stderr = std::str::from_utf8(unnormalized_stderr).unwrap();
|
||||
// erase annotations from the stderr so they don't match themselves
|
||||
let annotations = Regex::new(r"\s*//~.*").unwrap();
|
||||
let unnormalized_stderr = annotations.replace(unnormalized_stderr, "");
|
||||
let mut found_annotation = false;
|
||||
if let Some((ref error_pattern, definition_line)) = comments.error_pattern {
|
||||
if !unnormalized_stderr.contains(error_pattern) {
|
||||
|
|
|
|||
50
ui_test/src/tests.rs
Normal file
50
ui_test/src/tests.rs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use super::{check_annotations, Comments, Config, Error, Mode, OutputConflictHandling};
|
||||
|
||||
fn config() -> Config {
|
||||
Config {
|
||||
args: vec![],
|
||||
target: None,
|
||||
stderr_filters: vec![],
|
||||
stdout_filters: vec![],
|
||||
root_dir: PathBuf::from("."),
|
||||
mode: Mode::Fail,
|
||||
path_filter: None,
|
||||
program: PathBuf::from("cake"),
|
||||
output_conflict_handling: OutputConflictHandling::Error,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_2156() {
|
||||
let s = r"
|
||||
use std::mem;
|
||||
|
||||
fn main() {
|
||||
let _x: &i32 = unsafe { mem::transmute(16usize) }; //~ ERROR encountered a dangling reference (address $HEX is unallocated)
|
||||
}
|
||||
";
|
||||
let comments = Comments::parse(Path::new("<dummy>"), s);
|
||||
let mut errors = vec![];
|
||||
let config = config();
|
||||
let unnormalized_stderr = r"
|
||||
error: Undefined Behavior: type validation failed: encountered a dangling reference (address 0x10 is unallocated)
|
||||
--> tests/compile-fail/validity/dangling_ref1.rs:6:29
|
||||
|
|
||||
LL | let _x: &i32 = unsafe { mem::transmute(16usize) }; //~ ERROR encountered a dangling reference (address $HEX is unallocated)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling reference (address 0x10 is unallocated)
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
||||
= note: inside `main` at tests/compile-fail/validity/dangling_ref1.rs:6:29
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
error: aborting due to previous error
|
||||
";
|
||||
check_annotations(unnormalized_stderr.as_bytes(), &mut errors, &config, "", &comments);
|
||||
match &errors[..] {
|
||||
[Error::PatternNotFound { .. }] => {}
|
||||
_ => panic!("{:#?}", errors),
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue