]>
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 | |
94222f64 | 43 | //[thin0]compile-flags: -C opt-level=0 -C lto=thin |
e1599b0c XL |
44 | //[thin1]compile-flags: -C opt-level=1 -C lto=thin |
45 | //[thin2]compile-flags: -C opt-level=2 -C lto=thin | |
46 | //[thin3]compile-flags: -C opt-level=3 -C lto=thin | |
47 | //[fat0]compile-flags: -C opt-level=0 -C lto=fat | |
48 | //[fat1]compile-flags: -C opt-level=1 -C lto=fat | |
49 | //[fat2]compile-flags: -C opt-level=2 -C lto=fat | |
50 | //[fat3]compile-flags: -C opt-level=3 -C lto=fat | |
51 | ||
52 | fn main() { | |
53 | use std::sync::atomic::{AtomicUsize, Ordering}; | |
54 | ||
55 | static SHARED: AtomicUsize = AtomicUsize::new(0); | |
56 | ||
57 | assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 0); | |
58 | ||
59 | let old_hook = std::panic::take_hook(); | |
60 | ||
61 | std::panic::set_hook(Box::new(|_| { } )); // no-op on panic. | |
62 | ||
63 | let handle = std::thread::spawn(|| { | |
64 | struct Droppable; | |
65 | impl Drop for Droppable { | |
66 | fn drop(&mut self) { | |
67 | SHARED.fetch_add(1, Ordering::SeqCst); | |
68 | } | |
69 | } | |
70 | ||
71 | let _guard = Droppable; | |
72 | None::<()>.expect("???"); | |
73 | }); | |
74 | ||
75 | let wait = handle.join(); | |
76 | ||
77 | // reinstate handler to ease observation of assertion failures. | |
78 | std::panic::set_hook(old_hook); | |
79 | ||
80 | assert!(wait.is_err()); | |
81 | ||
82 | assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 1); | |
83 | } |