2019-10-20 20:46:04 -05:00
|
|
|
#include <assert.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
void println(const char* s) {
|
|
|
|
puts(s);
|
|
|
|
fflush(stdout);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct exception {};
|
2019-10-27 17:33:25 -05:00
|
|
|
struct rust_panic {};
|
2019-10-20 20:46:04 -05:00
|
|
|
|
|
|
|
struct drop_check {
|
|
|
|
bool* ok;
|
|
|
|
~drop_check() {
|
|
|
|
println("~drop_check");
|
|
|
|
|
|
|
|
if (ok)
|
|
|
|
*ok = true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
void rust_catch_callback(void (*cb)(), bool* rust_ok);
|
|
|
|
|
2020-03-21 02:50:38 -05:00
|
|
|
void throw_cxx_exception() {
|
2019-10-20 20:46:04 -05:00
|
|
|
println("throwing C++ exception");
|
|
|
|
throw exception();
|
|
|
|
}
|
|
|
|
|
2020-03-21 02:50:38 -05:00
|
|
|
void test_cxx_exception() {
|
2019-10-20 20:46:04 -05:00
|
|
|
bool rust_ok = false;
|
|
|
|
try {
|
2020-03-21 02:50:38 -05:00
|
|
|
rust_catch_callback(throw_cxx_exception, &rust_ok);
|
2019-10-20 20:46:04 -05:00
|
|
|
assert(false && "unreachable");
|
|
|
|
} catch (exception e) {
|
|
|
|
println("caught C++ exception");
|
|
|
|
assert(rust_ok);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
assert(false && "did not catch thrown C++ exception");
|
|
|
|
}
|
|
|
|
|
|
|
|
void cxx_catch_callback(void (*cb)(), bool* cxx_ok) {
|
|
|
|
drop_check x;
|
|
|
|
x.ok = NULL;
|
|
|
|
try {
|
|
|
|
cb();
|
2019-10-27 17:33:25 -05:00
|
|
|
} catch (rust_panic e) {
|
2019-10-20 20:46:04 -05:00
|
|
|
assert(false && "shouldn't be able to catch a rust panic");
|
|
|
|
} catch (...) {
|
|
|
|
println("caught foreign exception in catch (...)");
|
|
|
|
// Foreign exceptions are caught by catch (...). We only set the ok
|
|
|
|
// flag if we successfully caught the panic. The destructor of
|
|
|
|
// drop_check will then set the flag to true if it is executed.
|
|
|
|
x.ok = cxx_ok;
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|