From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- src/test/ui/panics/abort-on-panic.rs | 98 ++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/test/ui/panics/abort-on-panic.rs (limited to 'src/test/ui/panics/abort-on-panic.rs') diff --git a/src/test/ui/panics/abort-on-panic.rs b/src/test/ui/panics/abort-on-panic.rs new file mode 100644 index 000000000..1f6ad64c0 --- /dev/null +++ b/src/test/ui/panics/abort-on-panic.rs @@ -0,0 +1,98 @@ +// run-pass + +#![allow(unused_must_use)] +#![feature(c_unwind)] +#![feature(panic_always_abort)] +// Since we mark some ABIs as "nounwind" to LLVM, we must make sure that +// we never unwind through them. + +// ignore-emscripten no processes +// ignore-sgx no processes + +use std::io; +use std::io::prelude::*; +use std::process::{exit, Command, Stdio}; +use std::sync::{Arc, Barrier}; +use std::thread; +use std::{env, panic}; + +extern "C" fn panic_in_ffi() { + panic!("Test"); +} + +fn should_have_aborted() { + io::stdout().write(b"This should never be printed.\n"); + let _ = io::stdout().flush(); +} + +fn bomb_out_but_not_abort(msg: &str) { + eprintln!("bombing out: {}", msg); + exit(1); +} + +fn test() { + let _ = panic::catch_unwind(|| { + panic_in_ffi(); + }); + should_have_aborted(); +} + +fn test_always_abort() { + panic::always_abort(); + let _ = panic::catch_unwind(|| { + panic!(); + }); + should_have_aborted(); +} + +fn test_always_abort_thread() { + let barrier = Arc::new(Barrier::new(2)); + let thr = { + let barrier = barrier.clone(); + thread::spawn(move || { + barrier.wait(); + panic!("in thread"); + }) + }; + panic::always_abort(); + barrier.wait(); + let _ = thr.join(); + bomb_out_but_not_abort("joined - but we were supposed to panic!"); +} + +fn main() { + let tests: &[(_, fn())] = &[ + ("test", test), + ("test_always_abort", test_always_abort), + ("test_always_abort_thread", test_always_abort_thread), + ]; + + let args: Vec = env::args().collect(); + if args.len() > 1 { + // This is inside the self-executed command. + for (a, f) in tests { + if &args[1] == a { + return f(); + } + } + bomb_out_but_not_abort("bad test"); + } + + let execute_self_expecting_abort = |arg| { + let mut p = Command::new(&args[0]) + .stdout(Stdio::piped()) + .stdin(Stdio::piped()) + .arg(arg) + .spawn() + .unwrap(); + 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)); + }; + + for (a, _f) in tests { + execute_self_expecting_abort(a); + } +} -- cgit v1.2.3