]> git.lizzy.rs Git - rust.git/blob - src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
Rollup merge of #95376 - WaffleLapkin:drain_keep_rest, r=dtolnay
[rust.git] / src / test / ui / extern / issue-64655-allow-unwind-when-calling-panic-directly.rs
1 // run-pass
2 // needs-unwind
3 // ignore-wasm32-bare compiled with panic=abort by default
4 // ignore-emscripten no threads support
5
6 // rust-lang/rust#64655: with panic=unwind, a panic from a subroutine
7 // should still run destructors as it unwinds the stack. However,
8 // bugs with how the nounwind LLVM attribute was applied led to this
9 // simple case being mishandled *if* you had fat LTO turned on.
10
11 // Unlike issue-64655-extern-rust-must-allow-unwind.rs, the issue
12 // embodied in this test cropped up regardless of optimization level.
13 // Therefore it seemed worthy of being enshrined as a dedicated unit
14 // test.
15
16 // LTO settings cannot be combined with -C prefer-dynamic
17 // no-prefer-dynamic
18
19 // The revisions just enumerate lto settings (the opt-level appeared irrelevant in practice)
20
21 // revisions: no thin fat
22 //[no]compile-flags: -C lto=no
23 //[thin]compile-flags: -C lto=thin
24 //[fat]compile-flags: -C lto=fat
25
26 #![feature(core_panic)]
27
28 // (For some reason, reproducing the LTO issue requires pulling in std
29 // explicitly this way.)
30 #![no_std]
31 extern crate std;
32
33 fn main() {
34     use std::sync::atomic::{AtomicUsize, Ordering};
35     use std::boxed::Box;
36
37     static SHARED: AtomicUsize = AtomicUsize::new(0);
38
39     assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 0);
40
41     let old_hook = std::panic::take_hook();
42
43     std::panic::set_hook(Box::new(|_| { } )); // no-op on panic.
44
45     let handle = std::thread::spawn(|| {
46         struct Droppable;
47         impl Drop for Droppable {
48             fn drop(&mut self) {
49                 SHARED.fetch_add(1, Ordering::SeqCst);
50             }
51         }
52
53         let _guard = Droppable;
54         core::panicking::panic("???");
55     });
56
57     let wait = handle.join();
58
59     // Reinstate handler to ease observation of assertion failures.
60     std::panic::set_hook(old_hook);
61
62     assert!(wait.is_err());
63
64     assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 1);
65 }