rust-lang / rust-lang/rust-bindgen

Bindgen produces incorrect bindings to functions with 80-bit long doubles (f80)

Open
#2,378 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

Input C
// float_to_ld.h
long double float_to_ld(float f);

// float_to_ld.c
void test1(void);

long double float_to_ld(float f) {
    return f;
}

int main() {
    test1();
    return 0;
}
Bindgen Invocation

bindgen float_to_ld.h

Actual Results
extern "C" {
    pub fn float_to_ld(f: f32) -> u128;
}

#[no_mangle]
extern "C" fn test1() {
    let mut buf = [0; 10];
    for (i, x) in buf.iter_mut().enumerate() {
        *x ^= unsafe {
            float_to_ld(i as f32)
        };
    }
    println!("{buf:X?}");
}
[7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824, 7FFDF7F781F800005568AD1E4824]

This code fills up and overflows the x87 floating point stack, which doesn't crash the application but results in the stack containing nonsense values rather than the values 8.0, 9.0 expected. (This can be observed with gdb -ex start -ex 'layout asm' -ex 'tui reg float' float_to_ld.) Also the return values in the buffer are not the actual return values of the function as the wrong registers are being used.

As a more minor annoyance, even if the functions aren't used, rustc emits the warning note: 128-bit integers don't currently have a known stable ABI.

Expected Results

Either no bindings should be generated, or inline wrapper functions using inline assembly should be generated which correctly implement the calling convention. Given that Rust has no support for f80, simply omitting the bindings seems like the most pragmatic solution.

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 issue with the float_to_ld.h and float_to_ld.c examples using bindgen float_to_ld.h, then inspect how the generated Rust declaration represents the C long double return value. Compare the ABI behavior and warning with the expected omission of unsupported bindings; completion should prevent incorrect f80 bindings or provide a correct supported path.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.