| //@ only-wasm32 |
| //@ revisions: WASM WASMEXN |
| //@ [WASMEXN] compile-flags: -C panic=unwind -Z emscripten-wasm-eh |
| |
| #![crate_type = "lib"] |
| #![feature(core_intrinsics, wasm_exception_handling_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 [] |
| } |