rust-bindgen
rust-bindgen copied to clipboard
Fix test case from #2246
close #2246 fix align codegen of #2240 fix align codegen of #2159 fix align codegen of #1538
mm.. test passes only because test doesn't include case about:
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
struct A {
uint8_t a;
uint16_t b;
uint8_t c;
} __attribute__((aligned(2)));
struct B {
uint8_t a;
uint16_t b;
uint8_t c;
} __attribute__((aligned(2), packed));
#include <assert.h>
#include <stdio.h>
int main() {
printf("%lu %lu\n", sizeof(struct A), sizeof(struct B));
assert(sizeof(struct A) == sizeof(struct B));
}
is this the answer?
#[repr(C, align(2))]
#[derive(Debug, Default, Copy, Clone)]
pub struct B(B__packed);
#[repr(C, packed)]
#[derive(Debug, Default, Copy, Clone)]
pub struct B__packed {
pub a: u8,
pub b: u16,
pub c: u8,
}
#[test]
fn bindgen_test_layout_B() {
const UNINIT: ::std::mem::MaybeUninit<B> =
::std::mem::MaybeUninit::uninit();
let ptr = UNINIT.as_ptr();
assert_eq!(
::std::mem::size_of::<B>(),
4usize,
concat!("Size of: ", stringify!(B))
);
assert_eq!(
::std::mem::align_of::<B>(),
2usize,
concat!("Alignment of ", stringify!(B))
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).0.a) as usize - ptr as usize },
0usize,
concat!("Offset of field: ", stringify!(B), "::", stringify!(a))
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).0.b) as usize - ptr as usize },
1usize,
concat!("Offset of field: ", stringify!(B), "::", stringify!(b))
);
assert_eq!(
unsafe { ::std::ptr::addr_of!((*ptr).0.c) as usize - ptr as usize },
3usize,
concat!("Offset of field: ", stringify!(B), "::", stringify!(c))
);
}
I added the last commit to check the CI result. I don't believe that's the correct way. Please suppose I am not understanding the remaining problems and how bindgen handle packed and aligned.
@emilio do you have advices?
@emilio can I get advice for remaining issues?
Sorry for the lag, it's on my list of things to do. I plan to dig a bit into how C++ compilers treat repr+aligned hints because I'm not super-convinced there's a way to emulate it in Rust, but if you've done that research and can point to it it'd be extremely helpful.
I think emulating in rust is done here. I forgot the datails now but If you need explanation, I can review it again.
If bindgen cannot distinguish explicitly aligned and implicitly aligned struct, could you guide me to how to get clang-calcuated size and bindgen-calculated size for the struct? Then I will try to detect which alignment used by them.
:umbrella: The latest upstream changes (presumably #2284) made this pull request unmergeable. Please resolve the merge conflicts.
Can I kindly ask that this gets looked at please?
I've seen several issues and PRs discussing problems with packed and align representations. I'll gather some info and have a proper discussion around it with other contributors.