]>
Commit | Line | Data |
---|---|---|
e74abb32 XL |
1 | #include <assert.h> |
2 | #include <stddef.h> | |
3 | #include <stdio.h> | |
4 | ||
5 | void println(const char* s) { | |
6 | puts(s); | |
7 | fflush(stdout); | |
8 | } | |
9 | ||
10 | struct exception {}; | |
11 | struct rust_panic {}; | |
12 | ||
13 | struct drop_check { | |
14 | bool* ok; | |
15 | ~drop_check() { | |
16 | println("~drop_check"); | |
17 | ||
18 | if (ok) | |
19 | *ok = true; | |
20 | } | |
21 | }; | |
22 | ||
23 | extern "C" { | |
24 | void rust_catch_callback(void (*cb)(), bool* rust_ok); | |
25 | ||
1b1a35ee | 26 | void throw_cxx_exception() { |
e74abb32 XL |
27 | println("throwing C++ exception"); |
28 | throw exception(); | |
29 | } | |
30 | ||
1b1a35ee | 31 | void test_cxx_exception() { |
e74abb32 XL |
32 | bool rust_ok = false; |
33 | try { | |
1b1a35ee | 34 | rust_catch_callback(throw_cxx_exception, &rust_ok); |
e74abb32 XL |
35 | assert(false && "unreachable"); |
36 | } catch (exception e) { | |
37 | println("caught C++ exception"); | |
38 | assert(rust_ok); | |
39 | return; | |
40 | } | |
41 | assert(false && "did not catch thrown C++ exception"); | |
42 | } | |
43 | ||
44 | void cxx_catch_callback(void (*cb)(), bool* cxx_ok) { | |
45 | drop_check x; | |
46 | x.ok = NULL; | |
47 | try { | |
48 | cb(); | |
49 | } catch (rust_panic e) { | |
50 | assert(false && "shouldn't be able to catch a rust panic"); | |
51 | } catch (...) { | |
52 | println("caught foreign exception in catch (...)"); | |
53 | // Foreign exceptions are caught by catch (...). We only set the ok | |
54 | // flag if we successfully caught the panic. The destructor of | |
55 | // drop_check will then set the flag to true if it is executed. | |
56 | x.ok = cxx_ok; | |
57 | throw; | |
58 | } | |
59 | } | |
60 | } |