Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
youknowone opened this issue Jul 21, 2022 · 5 comments

Comments

@youknowone
Copy link

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))]
@emilio
Copy link
Contributor

emilio commented Jul 25, 2022

Ah, so I thought this was just a matter of something like #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?

@youknowone
Copy link
Author

youknowone commented Jul 26, 2022

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
Copy link
Author

youknowone commented Jul 26, 2022

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
Copy link
Author

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 pushed a commit to youknowone/rust-bindgen that referenced this issue Jul 28, 2022
@paravoid
Copy link

paravoid commented Jan 8, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants