]> git.proxmox.com Git - rustc.git/blame - src/test/run-make-fulldeps/foreign-exceptions/foo.rs
New upstream version 1.56.0~beta.4+dfsg1
[rustc.git] / src / test / run-make-fulldeps / foreign-exceptions / foo.rs
CommitLineData
1b1a35ee
XL
1// Tests that C++ exceptions can unwind through Rust code run destructors and
2// are caught by catch_unwind. Also tests that Rust panics can unwind through
e74abb32
XL
3// C++ code.
4
5// For linking libstdc++ on MinGW
6#![cfg_attr(all(windows, target_env = "gnu"), feature(static_nobundle))]
94222f64 7#![feature(c_unwind)]
e74abb32
XL
8
9use std::panic::{catch_unwind, AssertUnwindSafe};
10
11struct DropCheck<'a>(&'a mut bool);
12impl<'a> Drop for DropCheck<'a> {
13 fn drop(&mut self) {
14 println!("DropCheck::drop");
15 *self.0 = true;
16 }
17}
18
19extern "C" {
1b1a35ee 20 fn test_cxx_exception();
94222f64 21}
e74abb32 22
94222f64
XL
23extern "C-unwind" {
24 fn cxx_catch_callback(cb: extern "C-unwind" fn(), ok: *mut bool);
e74abb32
XL
25}
26
27#[no_mangle]
94222f64 28extern "C-unwind" fn rust_catch_callback(cb: extern "C-unwind" fn(), rust_ok: &mut bool) {
1b1a35ee
XL
29 let _drop = DropCheck(rust_ok);
30 cb();
31 unreachable!("should have unwound instead of returned");
e74abb32
XL
32}
33
1b1a35ee 34fn test_rust_panic() {
94222f64 35 extern "C-unwind" fn callback() {
e74abb32
XL
36 println!("throwing rust panic");
37 panic!(1234i32);
38 }
39
40 let mut dropped = false;
41 let mut cxx_ok = false;
42 let caught_unwind = catch_unwind(AssertUnwindSafe(|| {
43 let _drop = DropCheck(&mut dropped);
44 unsafe {
45 cxx_catch_callback(callback, &mut cxx_ok);
46 }
47 unreachable!("should have unwound instead of returned");
48 }));
49 println!("caught rust panic");
50 assert!(dropped);
51 assert!(caught_unwind.is_err());
52 let panic_obj = caught_unwind.unwrap_err();
53 let panic_int = *panic_obj.downcast_ref::<i32>().unwrap();
54 assert_eq!(panic_int, 1234);
55 assert!(cxx_ok);
56}
57
58fn main() {
1b1a35ee
XL
59 unsafe { test_cxx_exception() };
60 test_rust_panic();
e74abb32 61}