diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index d3fdfccd8a5..185aa3a5b40 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -1291,11 +1291,12 @@ fn catch_pad(&mut self, _parent: RValue<'gcc>, _args: &[RValue<'gcc>]) -> Funcle unimplemented!(); } - fn catch_switch(&mut self, _parent: Option>, _unwind: Option>, _num_handlers: usize) -> RValue<'gcc> { - unimplemented!(); - } - - fn add_handler(&mut self, _catch_switch: RValue<'gcc>, _handler: Block<'gcc>) { + fn catch_switch( + &mut self, + _parent: Option>, + _unwind: Option>, + _handlers: &[Block<'gcc>], + ) -> RValue<'gcc> { unimplemented!(); } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 7d62e5e8d41..02b9f23c4d6 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1028,7 +1028,7 @@ fn catch_switch( &mut self, parent: Option<&'ll Value>, unwind: Option<&'ll BasicBlock>, - num_handlers: usize, + handlers: &[&'ll BasicBlock], ) -> &'ll Value { let name = cstr!("catchswitch"); let ret = unsafe { @@ -1036,17 +1036,17 @@ fn catch_switch( self.llbuilder, parent, unwind, - num_handlers as c_uint, + handlers.len() as c_uint, name.as_ptr(), ) }; - ret.expect("LLVM does not have support for catchswitch") - } - - fn add_handler(&mut self, catch_switch: &'ll Value, handler: &'ll BasicBlock) { - unsafe { - llvm::LLVMRustAddHandler(catch_switch, handler); + let ret = ret.expect("LLVM does not have support for catchswitch"); + for handler in handlers { + unsafe { + llvm::LLVMRustAddHandler(ret, handler); + } } + ret } // Atomic Operations diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 5adfa18035a..f51d014bfb3 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -525,9 +525,8 @@ fn codegen_msvc_try<'ll>( normal.ret(bx.const_i32(0)); - let cs = catchswitch.catch_switch(None, None, 2); - catchswitch.add_handler(cs, catchpad_rust.llbb()); - catchswitch.add_handler(cs, catchpad_foreign.llbb()); + let cs = + catchswitch.catch_switch(None, None, &[catchpad_rust.llbb(), catchpad_foreign.llbb()]); // We can't use the TypeDescriptor defined in libpanic_unwind because it // might be in another DLL and the SEH encoding only supports specifying diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index b1a76b80002..ee7ca7f6e46 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1346,8 +1346,7 @@ fn landing_pad_for_uncached(&mut self, bb: mir::BasicBlock) -> Bx::BasicBlock { let mut cp_bx = self.new_block(&format!("cp_funclet{:?}", bb)); ret_llbb = cs_bx.llbb(); - let cs = cs_bx.catch_switch(None, None, 1); - cs_bx.add_handler(cs, cp_bx.llbb()); + let cs = cs_bx.catch_switch(None, None, &[cp_bx.llbb()]); // The "null" here is actually a RTTI type descriptor for the // C++ personality function, but `catch (...)` has no type so diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index f10d7c01df0..6c88241350f 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -441,9 +441,8 @@ fn catch_switch( &mut self, parent: Option, unwind: Option, - num_handlers: usize, + handlers: &[Self::BasicBlock], ) -> Self::Value; - fn add_handler(&mut self, catch_switch: Self::Value, handler: Self::BasicBlock); fn atomic_cmpxchg( &mut self,