@@ -265,15 +265,11 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
265265 let mut codegen_units = FnvHashMap ( ) ;
266266
267267 for trans_item in trans_items {
268- let is_root = match trans_item {
269- TransItem :: Static ( ..) => true ,
270- TransItem :: DropGlue ( ..) => false ,
271- TransItem :: Fn ( _) => !trans_item. is_from_extern_crate ( ) ,
272- } ;
268+ let is_root = !trans_item. is_instantiated_only_on_demand ( ) ;
273269
274270 if is_root {
275271 let characteristic_def_id = characteristic_def_id_of_trans_item ( tcx, trans_item) ;
276- let is_volatile = trans_item. is_lazily_instantiated ( ) ;
272+ let is_volatile = trans_item. is_generic_fn ( ) ;
277273
278274 let codegen_unit_name = match characteristic_def_id {
279275 Some ( def_id) => compute_codegen_unit_name ( tcx, def_id, is_volatile) ,
@@ -304,9 +300,9 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
304300 // it might be used in another codegen unit.
305301 llvm:: ExternalLinkage
306302 } else {
307- // Monomorphizations of generic functions are
308- // always weak-odr
309- llvm :: WeakODRLinkage
303+ // In the current setup, generic functions cannot
304+ // be roots.
305+ unreachable ! ( )
310306 }
311307 }
312308 }
@@ -395,25 +391,26 @@ fn place_inlined_translation_items<'tcx>(initial_partitioning: PreInliningPartit
395391 if let Some ( linkage) = codegen_unit. items . get ( & trans_item) {
396392 // This is a root, just copy it over
397393 new_codegen_unit. items . insert ( trans_item, * linkage) ;
394+ } else if initial_partitioning. roots . contains ( & trans_item) {
395+ // This item will be instantiated in some other codegen unit,
396+ // so we just add it here with AvailableExternallyLinkage
397+ new_codegen_unit. items . insert ( trans_item,
398+ llvm:: AvailableExternallyLinkage ) ;
399+ } else if trans_item. is_from_extern_crate ( ) && !trans_item. is_generic_fn ( ) {
400+ // It would be nice if we could mark these as
401+ // `AvailableExternallyLinkage`, since they should have
402+ // been instantiated in the extern crate. But this
403+ // sometimes leads to crashes on Windows because LLVM
404+ // does not handle exception handling table instantiation
405+ // reliably in that case.
406+ new_codegen_unit. items . insert ( trans_item, llvm:: InternalLinkage ) ;
398407 } else {
399- if initial_partitioning. roots . contains ( & trans_item) {
400- // This item will be instantiated in some other codegen unit,
401- // so we just add it here with AvailableExternallyLinkage
402- new_codegen_unit. items . insert ( trans_item,
403- llvm:: AvailableExternallyLinkage ) ;
404- } else if trans_item. is_from_extern_crate ( ) && !trans_item. is_generic_fn ( ) {
405- // An instantiation of this item is always available in the
406- // crate it was imported from.
407- new_codegen_unit. items . insert ( trans_item,
408- llvm:: AvailableExternallyLinkage ) ;
409- } else {
410- // We can't be sure if this will also be instantiated
411- // somewhere else, so we add an instance here with
412- // LinkOnceODRLinkage. That way the item can be discarded if
413- // it's not needed (inlined) after all.
414- new_codegen_unit. items . insert ( trans_item,
415- llvm:: LinkOnceODRLinkage ) ;
416- }
408+ assert ! ( trans_item. is_instantiated_only_on_demand( ) ) ;
409+ // We can't be sure if this will also be instantiated
410+ // somewhere else, so we add an instance here with
411+ // InternalLinkage so we don't get any conflicts.
412+ new_codegen_unit. items . insert ( trans_item,
413+ llvm:: InternalLinkage ) ;
417414 }
418415 }
419416
@@ -521,17 +518,25 @@ fn single_codegen_unit<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
521518 }
522519 }
523520 TransItem :: DropGlue ( _) => {
524- llvm:: PrivateLinkage
521+ llvm:: InternalLinkage
525522 }
526523 TransItem :: Fn ( instance) => {
527- if trans_item. is_generic_fn ( ) ||
528- trans_item. is_from_extern_crate ( ) ||
529- !reachable. contains ( & tcx. map
530- . as_local_node_id ( instance. def )
531- . unwrap ( ) ) {
524+ if trans_item. is_generic_fn ( ) {
532525 llvm:: InternalLinkage
533- } else {
526+ } else if trans_item. is_from_extern_crate ( ) {
527+ // It would be nice if we could mark these as
528+ // `AvailableExternallyLinkage`, since they should have
529+ // been instantiated in the extern crate. But this
530+ // sometimes leads to crashes on Windows because LLVM
531+ // does not handle exception handling table instantiation
532+ // reliably in that case.
533+ llvm:: InternalLinkage
534+ } else if reachable. contains ( & tcx. map
535+ . as_local_node_id ( instance. def )
536+ . unwrap ( ) ) {
534537 llvm:: ExternalLinkage
538+ } else {
539+ llvm:: InternalLinkage
535540 }
536541 }
537542 }
0 commit comments