about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2019-10-02 21:43:40 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2019-10-02 21:52:15 +0200
commita3719728325e7a6fa511aee5c8191c248262a9af (patch)
treea2df1e2574cabc6a9321024e20d2b03c12d4cac6
parent9fbb2a9b347d44074fff8aab27cd161a9cd54c74 (diff)
downloadrust-a3719728325e7a6fa511aee5c8191c248262a9af.tar.gz
rust-a3719728325e7a6fa511aee5c8191c248262a9af.zip
Regression tests for issue 64655.
-rw-r--r--src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs63
-rw-r--r--src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs82
2 files changed, 145 insertions, 0 deletions
diff --git a/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs b/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
new file mode 100644
index 00000000000..ac715e4328f
--- /dev/null
+++ b/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
@@ -0,0 +1,63 @@
+// run-pass
+
+// rust-lang/rust#64655: with panic=unwind, a panic from a subroutine
+// should still run desstructors as it unwindws the stack. However,
+// bugs with how the nounwind LLVM attribute was applied led to this
+// simple case being mishandled *if* you had fat LTO turned on.
+
+// Unlike issue-64655-extern-rust-must-allow-unwind.rs, the issue
+// embodied in this test cropped up regardless of optimization level.
+// Therefore it seemed worthy of being enshrined as a dedicated unit
+// test.
+
+// LTO settings cannot be combined with -C prefer-dynamic
+// no-prefer-dynamic
+
+// The revisions just enumerate lto settings (the opt-level appeared irrelevant in practice)
+
+// revisions: no thin fat
+//[no]compile-flags: -C lto=no
+//[thin]compile-flags: -C lto=thin
+//[fat]compile-flags: -C lto=fat
+
+#![feature(core_panic)]
+
+// (For some reason, reproducing the LTO issue requires pulling in std
+// explicitly this way.)
+#![no_std]
+extern crate std;
+
+fn main() {
+    use std::sync::atomic::{AtomicUsize, Ordering};
+    use std::boxed::Box;
+
+    static SHARED: AtomicUsize = AtomicUsize::new(0);
+
+    assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 0);
+
+    let old_hook = std::panic::take_hook();
+
+    std::panic::set_hook(Box::new(|_| { } )); // no-op on panic.
+
+    let handle = std::thread::spawn(|| {
+        struct Droppable;
+        impl Drop for Droppable {
+            fn drop(&mut self) {
+                SHARED.fetch_add(1, Ordering::SeqCst);
+            }
+        }
+
+        let _guard = Droppable;
+        let s = "issue-64655-allow-unwind-when-calling-panic-directly.rs";
+        core::panicking::panic(&("???", s, 17, 4));
+    });
+
+    let wait = handle.join();
+
+    // reinstate handler to ease observation of assertion failures.
+    std::panic::set_hook(old_hook);
+
+    assert!(wait.is_err());
+
+    assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 1);
+}
diff --git a/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs b/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
new file mode 100644
index 00000000000..4f7e8e3072f
--- /dev/null
+++ b/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
@@ -0,0 +1,82 @@
+// run-pass
+
+// rust-lang/rust#64655: with panic=unwind, a panic from a subroutine
+// should still run desstructors as it unwindws the stack. However,
+// bugs with how the nounwind LLVM attribute was applied led to this
+// simple case being mishandled *if* you had optimization *and* fat
+// LTO turned on.
+
+// This test is the closest thing to a "regression test" we can do
+// without actually spawning subprocesses and comparing stderr
+// results.
+//
+// This test takes the code from the above issue and adapts it to
+// better fit our test infrastructure:
+//
+// * Instead of relying on println! to observe whether the destructor
+//   is run, we instead run the code in a spawned thread and
+//   communicate the destructor's operation via a synchronous atomic
+//   in static memory.
+//
+// * To keep the output from confusing a casual user, we override the
+//   panic hook to be a no-op (rather than printing a message to
+//   stderr).
+//
+// (pnkfelix has confirmed by hand that these additions do not mask
+// the underlying bug.)
+
+// LTO settings cannot be combined with -C prefer-dynamic
+// no-prefer-dynamic
+
+// The revisions combine each lto setting with each optimization
+// setting; pnkfelix observed three differing behaviors at opt-levels
+// 0/1/2+3 for this test, so it seems prudent to be thorough.
+
+// revisions: no0 no1 no2 no3 thin0 thin1 thin2 thin3 fat0 fat1 fat2  fat3
+
+//[no0]compile-flags: -C opt-level=0 -C lto=no
+//[no1]compile-flags: -C opt-level=1 -C lto=no
+//[no2]compile-flags: -C opt-level=2 -C lto=no
+//[no3]compile-flags: -C opt-level=3 -C lto=no
+//[thin0]compile-flags: -C opt-level=0 -C lto=thin
+//[thin1]compile-flags: -C opt-level=1 -C lto=thin
+//[thin2]compile-flags: -C opt-level=2 -C lto=thin
+//[thin3]compile-flags: -C opt-level=3 -C lto=thin
+//[fat0]compile-flags: -C opt-level=0 -C lto=fat
+//[fat1]compile-flags: -C opt-level=1 -C lto=fat
+//[fat2]compile-flags: -C opt-level=2 -C lto=fat
+//[fat3]compile-flags: -C opt-level=3 -C lto=fat
+
+fn main() {
+    use std::sync::atomic::{AtomicUsize, Ordering};
+
+    static SHARED: AtomicUsize = AtomicUsize::new(0);
+
+    assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 0);
+
+    let old_hook = std::panic::take_hook();
+
+    std::panic::set_hook(Box::new(|_| { } )); // no-op on panic.
+
+    let handle = std::thread::spawn(|| {
+        struct Droppable;
+        impl Drop for Droppable {
+            fn drop(&mut self) {
+                SHARED.fetch_add(1, Ordering::SeqCst);
+            }
+        }
+
+        let _guard = Droppable;
+        None::<()>.expect("???");
+    });
+
+    let wait = handle.join();
+
+    // reinstate handler to ease observation of assertion failures.
+    std::panic::set_hook(old_hook);
+
+    assert!(wait.is_err());
+
+    assert_eq!(SHARED.fetch_add(0, Ordering::SeqCst), 1);
+}
+