]>
Commit | Line | Data |
---|---|---|
e1599b0c XL |
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 optimization *and* fat | |
9 | // LTO turned on. | |
10 | ||
11 | // This test is the closest thing to a "regression test" we can do | |
12 | // without actually spawning subprocesses and comparing stderr | |
13 | // results. | |
14 | // | |
15 | // This test takes the code from the above issue and adapts it to | |
16 | // better fit our test infrastructure: | |
17 | // | |
18 | // * Instead of relying on `println!` to observe whether the destructor | |
19 | // is run, we instead run the code in a spawned thread and | |
20 | // communicate the destructor's operation via a synchronous atomic | |
21 | // in static memory. | |
22 | // | |
23 | // * To keep the output from confusing a casual user, we override the | |
24 | // panic hook to be a no-op (rather than printing a message to | |
25 | // stderr). | |
26 | // | |
27 | // (pnkfelix has confirmed by hand that these additions do not mask | |
28 | // the underlying bug.) | |
29 | ||
30 | // LTO settings cannot be combined with -C prefer-dynamic | |
31 | // no-prefer-dynamic | |
32 | ||
33 | // The revisions combine each lto setting with each optimization | |
34 | // setting; pnkfelix observed three differing behaviors at opt-levels | |
35 | // 0/1/2+3 for this test, so it seems prudent to be thorough. | |
36 | ||
37 | // revisions: no0 no1 no2 no3 thin0 thin1 thin2 thin3 fat0 fat1 fat2 fat3 | |
38 | ||
39 | //[no0]compile-flags: -C opt-level=0 -C lto=no | |
40 | //[no1]compile-flags: -C opt-level=1 -C lto=no | |
41 | //[no2]compile-flags: -C opt-level=2 -C lto=no | |
42 | //[no3]compile-flags: -C opt-level=3 -C lto=no | |
cdc7bbd5 XL |
43 | // FIXME(#83854) running this revision with 1 CGU triggers llvm assert in register allocator |
44 | // when executed in dist-i586-gnu-i586-i686-musl runner. | |
45 | //[thin0]compile-flags: -C opt-level=0 -C lto=thin -Ccodegen-units=2 | |
e1599b0c XL |
46 | //[thin1]compile-flags: -C opt-level=1 -C lto=thin |
47 | //[thin2]compile-flags: -C opt-level=2 -C lto=thin | |
48 | //[thin3]compile-flags: -C opt-level=3 -C lto=thin | |
49 | //[fat0]compile-flags: -C opt-level=0 -C lto=fat | |
50 | //[fat1]compile-flags: -C opt-level=1 -C lto=fat | |
51 | //[fat2]compile-flags: -C opt-level=2 -C lto=fat | |
52 | //[fat3]compile-flags: -C opt-level=3 -C lto=fat | |
53 | ||
54 | fn main() { | |
55 | use std::sync::atomic::{AtomicUsize, Ordering}; | |
56 | ||
57 | static SHARED: AtomicUsize = AtomicUsize::new(0); | |
58 | ||
59 | assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 0); | |
60 | ||
61 | let old_hook = std::panic::take_hook(); | |
62 | ||
63 | std::panic::set_hook(Box::new(|_| { } )); // no-op on panic. | |
64 | ||
65 | let handle = std::thread::spawn(|| { | |
66 | struct Droppable; | |
67 | impl Drop for Droppable { | |
68 | fn drop(&mut self) { | |
69 | SHARED.fetch_add(1, Ordering::SeqCst); | |
70 | } | |
71 | } | |
72 | ||
73 | let _guard = Droppable; | |
74 | None::<()>.expect("???"); | |
75 | }); | |
76 | ||
77 | let wait = handle.join(); | |
78 | ||
79 | // reinstate handler to ease observation of assertion failures. | |
80 | std::panic::set_hook(old_hook); | |
81 | ||
82 | assert!(wait.is_err()); | |
83 | ||
84 | assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 1); | |
85 | } |