]> git.lizzy.rs Git - rust.git/commitdiff
Add a test to check that swallowed Rust panics are dropped properly.
authorAmanieu d'Antras <amanieu@gmail.com>
Sun, 29 Dec 2019 22:23:40 +0000 (23:23 +0100)
committerAmanieu d'Antras <amanieu@gmail.com>
Sat, 11 Jan 2020 10:18:44 +0000 (10:18 +0000)
src/test/run-make-fulldeps/foreign-exceptions/foo.cpp
src/test/run-make-fulldeps/foreign-exceptions/foo.rs

index b0fd65f88e7de9588ca35a263ecd4d5810fb2b8d..ef5cd74c6528315237d062ea23d99a95441bfd31 100644 (file)
@@ -57,4 +57,21 @@ extern "C" {
             throw;
         }
     }
+
+    void swallow_exception(void (*cb)()) {
+        try {
+            // Do a rethrow to ensure that the exception is only dropped once.
+            // This is necessary since we don't support copying exceptions.
+            try {
+                cb();
+            } catch (...) {
+                println("rethrowing Rust panic");
+                throw;
+            };
+        } catch (rust_panic e) {
+            assert(false && "shouldn't be able to catch a rust panic");
+        } catch (...) {
+            println("swallowing foreign exception in catch (...)");
+        }
+    }
 }
index 399c78f8d2d021cb7cdb80bc82400361666f7b6d..d9818dffc502bb10e0befeed2810061412c07182 100644 (file)
@@ -4,7 +4,6 @@
 
 // For linking libstdc++ on MinGW
 #![cfg_attr(all(windows, target_env = "gnu"), feature(static_nobundle))]
-
 #![feature(unwind_attributes)]
 
 use std::panic::{catch_unwind, AssertUnwindSafe};
@@ -20,6 +19,8 @@ fn drop(&mut self) {
 extern "C" {
     fn throw_cxx_exception();
 
+    fn swallow_exception(cb: extern "C" fn());
+
     #[unwind(allowed)]
     fn cxx_catch_callback(cb: extern "C" fn(), ok: *mut bool);
 }
@@ -60,7 +61,34 @@ extern "C" fn callback() {
     assert!(cxx_ok);
 }
 
+fn check_exception_drop() {
+    static mut DROP_COUNT: usize = 0;
+
+    struct CountDrop;
+    impl Drop for CountDrop {
+        fn drop(&mut self) {
+            println!("CountDrop::drop");
+            unsafe {
+                DROP_COUNT += 1;
+            }
+        }
+    }
+
+
+    #[unwind(allowed)]
+    extern "C" fn callback() {
+        println!("throwing rust panic #2");
+        panic!(CountDrop);
+    }
+
+    unsafe {
+        swallow_exception(callback);
+        assert_eq!(DROP_COUNT, 1);
+    }
+}
+
 fn main() {
     unsafe { throw_cxx_exception() };
     throw_rust_panic();
+    check_exception_drop();
 }