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