rust-lang / rust-lang/rust-bindgen
Bindgen produces incorrect bindings to functions with 80-bit long doubles (f80)
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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