@@ -443,6 +443,35 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code
443
443
if tcx. should_inherit_track_caller ( did) {
444
444
codegen_fn_attrs. flags |= CodegenFnAttrFlags :: TRACK_CALLER ;
445
445
}
446
+
447
+ // Foreign items by default use no mangling for their symbol name.
448
+ if tcx. is_foreign_item ( did) {
449
+ // There's a few exceptions to this rule though:
450
+ if codegen_fn_attrs. flags . contains ( CodegenFnAttrFlags :: RUSTC_STD_INTERNAL_SYMBOL ) {
451
+ // * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way
452
+ // both for exports and imports through foreign items. This is handled further,
453
+ // during symbol mangling logic/
454
+ } else if codegen_fn_attrs. link_name . is_some ( ) {
455
+ // * This can be overridden with the `#[link_name]` attribute
456
+ } else if tcx. sess . target . is_like_wasm
457
+ && tcx. wasm_import_module_map ( LOCAL_CRATE ) . contains_key ( & did. into ( ) )
458
+ {
459
+ // * On the wasm32 targets there is a bug (or feature) in LLD [1] where the
460
+ // same-named symbol when imported from different wasm modules will get
461
+ // hooked up incorrectly. As a result foreign symbols, on the wasm target,
462
+ // with a wasm import module, get mangled. Additionally our codegen will
463
+ // deduplicate symbols based purely on the symbol name, but for wasm this
464
+ // isn't quite right because the same-named symbol on wasm can come from
465
+ // different modules. For these reasons if `#[link(wasm_import_module)]`
466
+ // is present we mangle everything on wasm because the demangled form will
467
+ // show up in the `wasm-import-name` custom attribute in LLVM IR.
468
+ //
469
+ // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316
470
+ } else {
471
+ // if none of the exceptions apply; apply no_mangle
472
+ codegen_fn_attrs. flags |= CodegenFnAttrFlags :: NO_MANGLE ;
473
+ }
474
+ }
446
475
}
447
476
448
477
fn check_result (
0 commit comments