Skip to content

Binary build fails if two crates exported same function with #[no_mangle] and LTO enabled #98666

@ValeryAntopol

Description

@ValeryAntopol

When linking crates which both export function with the same name with #[no_mangle], LTO fails to process it and emits a message that cannot be understood without looking into rustc sources. For simplicity, i put a minimal reproducible example into a repo https://github.com/ValeryAntopol/rust-lto-bug. The helper crate builds to a library with default settings, rust-lto-bug builds to a binary with default settings + LTO enabled, links with the helper crate.

I tried this code:

helper/lib.rs:

#[no_mangle] pub fn foo() {}

main.rs:

#[allow(unused)] use helper; #[no_mangle] pub fn foo() {} fn main() {}

I expected to see this happen:
One of the following:

  • successful compilation where LTO somehow handles it (compilation without LTO works successfully, why should one with LTO enabled fail?)
  • compilation/linking error saying that it failed because of a function exported twice

I also expect that the behavior will be the same for both enabled and disabled LTO, but i understand that it could be too difficult to achieve.

Instead, this happened:

cargo build, LTO enabled:

 Compiling helper v0.1.0 (/Users/valeryantopol/work/rust-lto-bug/helper) Compiling rust-lto-bug v0.1.0 (/Users/valeryantopol/work/rust-lto-bug) warning: Linking globals named 'foo': symbol multiply defined! error: failed to load bitcode of module "sqkmfdx3qawf5f0": warning: `rust-lto-bug` (bin "rust-lto-bug") generated 1 warning error: could not compile `rust-lto-bug` due to previous error; 1 warning emitted 

cargo build --release, LTO enabled:

 Compiling helper v0.1.0 (/Users/valeryantopol/work/rust-lto-bug/helper) Compiling rust-lto-bug v0.1.0 (/Users/valeryantopol/work/rust-lto-bug) warning: Linking globals named 'foo': symbol multiply defined! error: failed to load bitcode of module "rust_lto_bug.db9ad83a-cgu.1": warning: `rust-lto-bug` (bin "rust-lto-bug") generated 1 warning error: could not compile `rust-lto-bug` due to previous error; 1 warning emitted 

cargo build, LTO disabled:

 Compiling helper v0.1.0 (/Users/valeryantopol/work/rust-lto-bug/helper) Compiling rust-lto-bug v0.1.0 (/Users/valeryantopol/work/rust-lto-bug) Finished dev [unoptimized + debuginfo] target(s) in 0.70s 

Meta

Versions checked:

rustc 1.61.0 (fe5b13d68 2022-05-18) rustc 1.64.0-nightly (830880640 2022-06-28) rustc 1.63.0-beta.2 (6c1f14289 2022-06-28) 

On all of them behavior is the same, only the module hash changes. But it is the same on different compilations with the same version.

RUST_BACKTACE=1 adds nothing to the output.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-linkageArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions