rust-lang / rust-lang/rust-bindgen
Avoid use of non-FFI safe type u128 for alignment
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 5.3k
- Forks
- 829
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 15
Description
Input C/C++ Header
typedef struct _Foo {} __attribute__((__aligned__(16))) Foo;
typedef struct _Bar {} __attribute__((__aligned__(16))) Bar;
Foo *foo_new();
Bar *bar_new();
Bindgen Invocation
$ bindgen input.h --allowlist-function '.*' --opaque-type Foo --opaque-type _Bar --no-layout-tests
Actual Results
/* automatically generated by rust-bindgen 0.59.1 */
pub type Foo = [u128; 0usize];
#[repr(C)]
#[repr(align(16))]
#[derive(Debug, Copy, Clone)]
pub struct _Bar {
pub _bindgen_opaque_blob: [u128; 0usize],
}
pub type Bar = _Bar;
extern "C" {
pub fn foo_new() -> *mut Foo;
}
extern "C" {
pub fn bar_new() -> *mut Bar;
}
Expected Results
The issue with this codegen is that u128 is used to get the 16-bytes alignment, but its use causes warnings:
warning: `extern` block uses type `u128`, which is not FFI-safe
--> new.rs:25:25
|
25 | pub fn foo_new() -> *mut Foo;
| ^^^^^^^^ not FFI-safe
|
= note: `#[warn(improper_ctypes)]` on by default
= note: 128-bit integers don't currently have a known stable ABI
Instead, it would be better if the generated code used the #[repr(align(16))] for alignment, and only used u8 for sizes. However, this isn't always easily doable.
I included both Foo and Bar examples because the bar one is easily fixable, replacing u128 with u8, as the struct is properly aligned.
However, in the case of Foo, #[repr(align(...))] cannot be used directly. A solution would be to codegen:
#[repr(align(16))]
pub struct Foo([u8; 0usize]);
or to do the same codegen as is done for _Bar:
#[repr(align(16))]
pub struct Foo {
pub _bindgen_opaque_blob = [u8; 0usize],
}
i'm not entirely sure when bindgen decides to use a type alias, or use a struct with a single opaque field.
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
Start by reproducing the bindgen invocation with the supplied input.h and compare the generated representations of Foo and Bar. Trace the codegen path that chooses the type alias or opaque struct form; done means aligned opaque types use u8-based storage and avoid the u128 FFI-safety warning while preserving the required alignment.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100