@@ -954,19 +954,39 @@ fn codegen_msvc_try(
954
954
let cs = catchswitch. catch_switch ( None , None , 1 ) ;
955
955
catchswitch. add_handler ( cs, catchpad. llbb ( ) ) ;
956
956
957
+ // We can't use the TypeDescriptor defined in libpanic_unwind because it
958
+ // might be in another DLL and the SEH encoding only supports specifying
959
+ // a TypeDescriptor from the current module.
960
+ //
961
+ // However this isn't an issue since the MSVC runtime uses string
962
+ // comparison on the type name to match TypeDescriptors rather than
963
+ // pointer equality.
964
+ //
965
+ // So instead we generate a new TypeDescriptor in each module that uses
966
+ // `try` and let the linker merge duplicate definitions in the same
967
+ // module.
968
+ //
969
+ // When modifying, make sure that the type_name string exactly matches
970
+ // the one used in src/libpanic_unwind/seh.rs.
971
+ let type_info_vtable = bx. declare_global ( "??_7type_info@@6B@" , bx. type_i8p ( ) ) ;
972
+ let type_name = bx. const_bytes ( b"rust_panic\0 " ) ;
973
+ let type_info =
974
+ bx. const_struct ( & [ type_info_vtable, bx. const_null ( bx. type_i8p ( ) ) , type_name] , false ) ;
975
+ let tydesc = bx. declare_global ( "__rust_panic_type_info" , bx. val_ty ( type_info) ) ;
976
+ unsafe {
977
+ llvm:: LLVMRustSetLinkage ( tydesc, llvm:: Linkage :: LinkOnceODRLinkage ) ;
978
+ llvm:: SetUniqueComdat ( bx. llmod , tydesc) ;
979
+ llvm:: LLVMSetInitializer ( tydesc, type_info) ;
980
+ }
981
+
957
982
// The flag value of 8 indicates that we are catching the exception by
958
983
// reference instead of by value. We can't use catch by value because
959
984
// that requires copying the exception object, which we don't support
960
985
// since our exception object effectively contains a Box.
961
986
//
962
987
// Source: MicrosoftCXXABI::getAddrOfCXXCatchHandlerType in clang
963
988
let flags = bx. const_i32 ( 8 ) ;
964
- let tydesc = match bx. tcx ( ) . lang_items ( ) . eh_catch_typeinfo ( ) {
965
- Some ( did) => bx. get_static ( did) ,
966
- None => bug ! ( "eh_catch_typeinfo not defined, but needed for SEH unwinding" ) ,
967
- } ;
968
989
let funclet = catchpad. catch_pad ( cs, & [ tydesc, flags, slot] ) ;
969
-
970
990
let i64_align = bx. tcx ( ) . data_layout . i64_align . abi ;
971
991
let payload_ptr = catchpad. load ( slot, ptr_align) ;
972
992
let payload = catchpad. load ( payload_ptr, i64_align) ;
0 commit comments