Skip to content

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

Closed as not planned
@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