rust-lang / rust-lang/rust

Linking a Rust staticlib unexpectedly changes C math functions from libm to bundled ones from compiler-builtins

Open
#142,119 21 comments 5 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-compiler-builtins A-linkage C-bug E-hard E-help-wanted P-medium regression-from-stable-to-stable T-compiler T-libs
Dominant language
Rust
Stars
119k
Forks
16.2k
PR merge metrics
PR metrics pending

Description

View all comments

Code

Given a staticlib with the source:

#[unsafe(no_mangle)]
pub extern "C" fn demo() -> f32 {
    let x : f32 = 1.1;
    x.ceil()
}

compiled as crate-type = ["staticlib"] and the C program:

#include <math.h>
#include <stdio.h>

float demo();

int main(int argc, char** argv) {
    float x = -1.2;
    printf("%f\n", ceilf(x));
    printf("%f\n", demo());
    return 0;
}

When linking the program like this: $(CC) main.o as-crate/target/debug/libas_crate.a -lm -o out/tgt-from-crate the resulting binary ends up using ceilf from compiler-builtins rather than libm.

I expected to see this happen: The binary should still get ceilf from libm, eg

$ nm -uD out/tgt-from-crate | grep ceilf || true
                 U ceilf@GLIBC_2.2.5

Instead, this happened: Instead, the ceilf symbol was satisfied by the matching symbol in compiler-builtins, and so the C call was surprise-migrated to a different implementation.

Version it worked on

1.86
rustc --version --verbose:

rustc 1.86.0 (05f9846f8 2025-03-31)
binary: rustc
commit-hash: 05f9846f893b09a1be1fc8560e33fc3c815cfecb
commit-date: 2025-03-31
host: x86_64-unknown-linux-gnu
release: 1.86.0
LLVM version: 19.1.7
Version with regression

1.87
rustc --version --verbose:

rustc 1.87.0 (17067e9ac 2025-05-09)
binary: rustc
commit-hash: 17067e9ac6d7ecb70e50f92c1944e545188d2359
commit-date: 2025-05-09
host: x86_64-unknown-linux-gnu
release: 1.87.0
LLVM version: 20.1.1
Additional information

I suspect this is related to some work tracked in #137578. I also found out Chromium has already stumbled on this: https://issues.chromium.org/issues/419258012#comment5 and for them it caused observable behavior changes. Apologies for not catching this sooner - we hadn't upgraded compiler-builtins for a while and didn't notice until a couple of weeks ago. :(

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the staticlib and C program from the issue with Rust 1.86 and 1.87, then inspect the generated symbols and link behavior around compiler-builtins and libm. Read the work tracked in #137578 for context; done means the C call to ceilf remains satisfied by libm rather than being replaced by compiler-builtins.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, rust
Domain
build-system, compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.