| //@ only-wasm32 | |
| //@ revisions: WASM WASMEXN | |
| //@ [WASMEXN] compile-flags: -C panic=unwind -Z emscripten-wasm-eh | |
| #![crate_type = "lib"] | |
| #![feature(core_intrinsics, link_llvm_intrinsics)] | |
| extern "C-unwind" { | |
| fn may_panic(); | |
| } | |
| extern "C" { | |
| fn log_number(number: usize); | |
| } | |
| struct LogOnDrop; | |
| impl Drop for LogOnDrop { | |
| fn drop(&mut self) { | |
| unsafe { | |
| log_number(0); | |
| } | |
| } | |
| } | |
| // WASM-LABEL: @test_cleanup() {{.*}} | |
| // WASMEXN-LABEL: @test_cleanup() {{.*}} @__gxx_wasm_personality_v0 | |
| #[no_mangle] | |
| pub fn test_cleanup() { | |
| let _log_on_drop = LogOnDrop; | |
| unsafe { | |
| may_panic(); | |
| } | |
| // WASMEXN-NOT: call | |
| // WASMEXN: invoke void @may_panic() | |
| // WASMEXN: %cleanuppad = cleanuppad within none [] | |
| // | |
| // WASM: call void @may_panic() | |
| // WASM-NOT: invoke void @may_panic() | |
| } | |
| // WASM-LABEL: @test_rtry() {{.*}} | |
| // WASMEXN-LABEL: @test_rtry() {{.*}} @__gxx_wasm_personality_v0 | |
| #[no_mangle] | |
| pub fn test_rtry() { | |
| unsafe { | |
| core::intrinsics::catch_unwind( | |
| |_| { | |
| may_panic(); | |
| }, | |
| core::ptr::null_mut(), | |
| |data, exception| { | |
| log_number(data as usize); | |
| log_number(exception as usize); | |
| }, | |
| ); | |
| } | |
| // WASMEXN-NOT: call | |
| // WASMEXN: invoke void @may_panic() | |
| // WASMEXN: {{.*}} = catchswitch within none [label {{.*}}] unwind to caller | |
| // WASMEXN: {{.*}} = catchpad within {{.*}} [ptr null] | |
| // WASMEXN: catchret | |
| // WASM: call void @may_panic() | |
| // WASM-NOT: invoke void @may_panic() | |
| // WASM-NOT: catchswitch | |
| // WASM-NOT: catchpad | |
| // WASM-NOT: catchret | |
| } | |
| // Make sure the intrinsic is not inferred as nounwind. This is a regression test for #132416. | |
| // | |
| // Note that this test uses the raw `wasm_throw` intrinsic because the one from | |
| // libstd was built with `-Cpanic=abort` and it's technically not valid to use | |
| // when this crate is compiled with `-Cpanic=unwind`. | |
| // | |
| // WASMEXN-LABEL: @test_intrinsic() {{.*}} @__gxx_wasm_personality_v0 | |
| #[no_mangle] | |
| #[cfg(wasmexn)] | |
| pub fn test_intrinsic() { | |
| let _log_on_drop = LogOnDrop; | |
| unsafe extern "C-unwind" { | |
| #[link_name = "llvm.wasm.throw"] | |
| fn wasm_throw(tag: i32, ptr: *mut u8) -> !; | |
| } | |
| unsafe { | |
| wasm_throw(0, core::ptr::null_mut()); | |
| } | |
| // WASMEXN-NOT: call | |
| // WASMEXN: invoke void @llvm.wasm.throw(i32 noundef 0, ptr noundef null) | |
| // WASMEXN: %cleanuppad = cleanuppad within none [] | |
| } |