Description
(Apologies if this already reported in some form: GitHub search shows a lot of semi-related open issues but none seem to define exactly this scenario - even if they may share the same problem in the end)
Consider the following bindings.hpp
sample:
#pragma pack(4)
class Data {
void *test;
};
class Foo {
virtual void foo();
};
Running bindgen bindings.hpp
(with a 64-bit target) prints:
/* automatically generated by rust-bindgen 0.71.1 */
#[repr(C, packed(4))]
#[derive(Debug, Copy, Clone)]
pub struct Data {
pub test: *mut ::std::os::raw::c_void,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
["Size of Data"][::std::mem::size_of::<Data>() - 8usize];
["Alignment of Data"][::std::mem::align_of::<Data>() - 4usize];
["Offset of field: Data::test"][::std::mem::offset_of!(Data, test) - 0usize];
};
#[repr(C)]
pub struct Foo__bindgen_vtable(::std::os::raw::c_void);
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo {
pub vtable_: *const Foo__bindgen_vtable,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
["Size of Foo"][::std::mem::size_of::<Foo>() - 8usize];
["Alignment of Foo"][::std::mem::align_of::<Foo>() - 4usize];
};
It seems that the layout tests picked up the #pragma pack(4)
and expect an alignment of 4
for both Data
and Foo
(both contain pointer fields that are otherwise aligned to 8
bytes). However, packed(4)
is only emitted for the "POD" Data
structure but not for the Foo
virtual class, meaning that these layout tests will now fail:
❯ rustc bindings.rs
...
error[E0080]: evaluation of constant value failed
--> bindings.rs:24:5
|
24 | ["Alignment of Foo"][::std::mem::align_of::<Foo>() - 4usize];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 4
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0080, E0601.
For more information about an error, try `rustc --explain E0080`.
The repr(C, packed(4))
should be emitted on struct Foo
, and the alignment test is correct. After all, printing alignof(Foo)
for the above code is 4
in cpp
too.
#include <iostream>
#pragma pack(4)
class Foo {
virtual void foo();
};
int main() {
std::cout << alignof(Foo) << std::endl;
}
$ clang -lstdc++ bindings.cpp && ./a.out
4
Activity