diff options
Diffstat (limited to 'compiler/rustc_codegen_ssa')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/block.rs | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 4be363ca9a2..2eecf81a5d2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1708,15 +1708,32 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let mut cs_bx = Bx::build(self.cx, llbb); let cs = cs_bx.catch_switch(None, None, &[cp_llbb]); - // The "null" here is actually a RTTI type descriptor for the - // C++ personality function, but `catch (...)` has no type so - // it's null. The 64 here is actually a bitfield which - // represents that this is a catch-all block. bx = Bx::build(self.cx, cp_llbb); let null = bx.const_null(bx.type_ptr_ext(bx.cx().data_layout().instruction_address_space)); - let sixty_four = bx.const_i32(64); - funclet = Some(bx.catch_pad(cs, &[null, sixty_four, null])); + + // The `null` in first argument here is actually a RTTI type + // descriptor for the C++ personality function, but `catch (...)` + // has no type so it's null. + let args = if base::wants_msvc_seh(self.cx.sess()) { + // This bitmask is a single `HT_IsStdDotDot` flag, which + // represents that this is a C++-style `catch (...)` block that + // only captures programmatic exceptions, not all SEH + // exceptions. The second `null` points to a non-existent + // `alloca` instruction, which an LLVM pass would inline into + // the initial SEH frame allocation. + let adjectives = bx.const_i32(0x40); + &[null, adjectives, null] as &[_] + } else { + // Specifying more arguments than necessary usually doesn't + // hurt, but the `WasmEHPrepare` LLVM pass does not recognize + // anything other than a single `null` as a `catch (...)` block, + // leading to problems down the line during instruction + // selection. + &[null] as &[_] + }; + + funclet = Some(bx.catch_pad(cs, args)); } else { llbb = Bx::append_block(self.cx, self.llfn, "terminate"); bx = Bx::build(self.cx, llbb); |
