2019-07-26 21:54:25 +00:00
|
|
|
// run-pass
|
|
|
|
|
2018-09-14 10:20:28 +00:00
|
|
|
#![allow(unused_must_use)]
|
2019-02-28 00:21:31 +00:00
|
|
|
#![feature(unwind_attributes)]
|
2017-12-19 00:59:29 +00:00
|
|
|
// Since we mark some ABIs as "nounwind" to LLVM, we must make sure that
|
|
|
|
// we never unwind through them.
|
|
|
|
|
|
|
|
// ignore-emscripten no processes
|
2019-04-24 16:26:33 +00:00
|
|
|
// ignore-sgx no processes
|
2017-12-19 00:59:29 +00:00
|
|
|
|
|
|
|
use std::{env, panic};
|
|
|
|
use std::io::prelude::*;
|
|
|
|
use std::io;
|
|
|
|
use std::process::{Command, Stdio};
|
|
|
|
|
2019-10-12 19:02:38 +00:00
|
|
|
#[unwind(aborts)] // FIXME(#58794) should work even without the attribute
|
2017-12-19 00:59:29 +00:00
|
|
|
extern "C" fn panic_in_ffi() {
|
|
|
|
panic!("Test");
|
|
|
|
}
|
|
|
|
|
2019-10-12 19:02:38 +00:00
|
|
|
#[unwind(aborts)]
|
|
|
|
extern "Rust" fn panic_in_rust_abi() {
|
|
|
|
panic!("TestRust");
|
|
|
|
}
|
|
|
|
|
2021-02-07 12:16:11 +00:00
|
|
|
fn should_have_aborted() {
|
2017-12-19 00:59:29 +00:00
|
|
|
io::stdout().write(b"This should never be printed.\n");
|
|
|
|
let _ = io::stdout().flush();
|
|
|
|
}
|
|
|
|
|
2021-04-22 14:05:23 +00:00
|
|
|
fn bomb_out_but_not_abort(msg: &str) {
|
|
|
|
eprintln!("bombing out: {}", msg);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2021-02-07 12:16:11 +00:00
|
|
|
fn test() {
|
|
|
|
let _ = panic::catch_unwind(|| { panic_in_ffi(); });
|
|
|
|
should_have_aborted();
|
|
|
|
}
|
|
|
|
|
2019-10-12 19:02:38 +00:00
|
|
|
fn testrust() {
|
|
|
|
let _ = panic::catch_unwind(|| { panic_in_rust_abi(); });
|
2021-02-07 12:16:11 +00:00
|
|
|
should_have_aborted();
|
2019-10-12 19:02:38 +00:00
|
|
|
}
|
|
|
|
|
2017-12-19 00:59:29 +00:00
|
|
|
fn main() {
|
2021-02-07 12:16:11 +00:00
|
|
|
let tests: &[(_, fn())] = &[
|
|
|
|
("test", test),
|
|
|
|
("testrust", testrust),
|
|
|
|
];
|
|
|
|
|
2017-12-19 00:59:29 +00:00
|
|
|
let args: Vec<String> = env::args().collect();
|
2019-10-12 19:02:38 +00:00
|
|
|
if args.len() > 1 {
|
|
|
|
// This is inside the self-executed command.
|
2021-02-07 12:16:11 +00:00
|
|
|
for (a,f) in tests {
|
|
|
|
if &args[1] == a { return f() }
|
2019-10-12 19:02:38 +00:00
|
|
|
}
|
2021-04-22 14:05:23 +00:00
|
|
|
bomb_out_but_not_abort("bad test");
|
2017-12-19 00:59:29 +00:00
|
|
|
}
|
|
|
|
|
2021-02-07 12:16:11 +00:00
|
|
|
let execute_self_expecting_abort = |arg| {
|
|
|
|
let mut p = Command::new(&args[0])
|
|
|
|
.stdout(Stdio::piped())
|
|
|
|
.stdin(Stdio::piped())
|
|
|
|
.arg(arg).spawn().unwrap();
|
2021-04-22 14:05:23 +00:00
|
|
|
let status = p.wait().unwrap();
|
|
|
|
assert!(!status.success());
|
|
|
|
// Any reasonable platform can distinguish a process which
|
|
|
|
// called exit(1) from one which panicked.
|
|
|
|
assert_ne!(status.code(), Some(1));
|
2021-02-07 12:16:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
for (a,_f) in tests {
|
|
|
|
execute_self_expecting_abort(a);
|
|
|
|
}
|
2017-12-19 00:59:29 +00:00
|
|
|
}
|