rust-bindgen
rust-bindgen copied to clipboard
Avoid use of non-FFI safe type u128 for alignment
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.