rust-bindgen icon indicating copy to clipboard operation
rust-bindgen copied to clipboard

__attribute__((aligned(2), packed)) generates both repr(packed) and repr(aligned)

Open youknowone opened this issue 3 years ago • 5 comments

Input C/C++ Header

part of MacOSX.sdk/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/hfs/hfs_format.h

#define int8_t char

struct FndrOpaqueInfo {
        int8_t opaque[16];
} __attribute__((aligned(2), packed));

Bindgen Invocation

$ bindgen has_format.h

Actual Results

#[repr(C, packed(2))]
#[repr(align(2))]
#[derive(Debug, Copy, Clone)]
pub struct FndrOpaqueInfo {
    pub opaque: [::std::os::raw::c_char; 16usize],
}

Expected Results

#[repr(C, packed(2))]
#[derive(Debug, Copy, Clone)]
pub struct FndrOpaqueInfo {
    pub opaque: [::std::os::raw::c_char; 16usize],
}

The actual result is illegal in Rust.

#[repr(C, packed(2))]
#[repr(align(2))]

any of below will be accepted

#[repr(C, packed(2))]
#[repr(C)]
#[repr(align(2))]

youknowone avatar Jul 21 '22 02:07 youknowone

Ah, so I thought this was just a matter of something like https://github.com/rust-lang/rust-bindgen/pull/2246, but it seems repr(packed(2)) in Rust has a different behavior than that C code, and I'm not sure how to get the right layout for __attribute__((aligned(2), packed)).

For that struct, which doesn't have padding, __attribute__(aligned(2)) would be enough, but that's not ok in the general case. This might need rust changes?

emilio avatar Jul 25 '22 09:07 emilio

The document seems describing packed(2) means it is aligned by 2 when layout fits. is it a rustc bug?

For packed, if the specified alignment is greater than the type's alignment without the packed modifier, then the alignment and layout is unaffected.

youknowone avatar Jul 26 '22 21:07 youknowone

I misunderstood the description.

#[repr(C, packed(2))]
struct S1 {
  field: [u8; 16],
}

#[repr(C, packed(2))]
struct S2 {
  field: [u16; 8],
}

fn main() {
  println!("align of {} {}",
    std::mem::align_of::<S1>(),
    std::mem::align_of::<S2>(),
  );
}
$ ./x 
align of 1 2

It was not affected because the inner type was not aligned

youknowone avatar Jul 26 '22 21:07 youknowone

I can tell my suggestion for expected result came from lack of knowledge of rust packed(N) and your patch actually fixed the problem.

For my case, I may be able to fix it with the patch + opaque_type option to FndrOpaqueInfo

youknowone avatar Jul 26 '22 21:07 youknowone

The patch seems to be working -- any reason not to merge at this point?

paravoid avatar Jan 08 '24 08:01 paravoid