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

csmith: Wrong size of struct with bitfields #1076

Closed
pepyakin opened this issue Oct 11, 2017 · 3 comments
Closed

csmith: Wrong size of struct with bitfields #1076

pepyakin opened this issue Oct 11, 2017 · 3 comments

Comments

@pepyakin
Copy link
Contributor

Input C/C++ Header

struct S1 {
  signed : 15;
  unsigned : 6
};

Bindgen Invocation

Predicate invocation:

predicate.py \
    --bindings-grep "S1" \
    --expect-layout-tests-fail \
    --layout-tests-grep "Size of\: S1" \
    ./header.h

(bindgen args)

Actual Results

Layout test panic:

thread 'bindgen_test_layout_S1' panicked at 'assertion failed: `(left == right)`
  left: `4`,
 right: `3`: Size of: S1', /var/folders/cd/c9707gm91qj22fkb99clygfm0000gn/T/bindings-q9aa57t5.rs:3:207

Generated bindings:

/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Debug, Default, Copy, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct S1 {
    pub _bitfield_1: [u16; 2usize],
    pub __bindgen_align: [u8; 0usize],
}
#[test]
fn bindgen_test_layout_S1() {
    assert_eq!(
        ::std::mem::size_of::<S1>(),
        3usize,
        concat!("Size of: ", stringify!(S1))
    );
    assert_eq!(
        ::std::mem::align_of::<S1>(),
        1usize,
        concat!("Alignment of ", stringify!(S1))
    );
}
impl Clone for S1 {
    fn clone(&self) -> Self {
        *self
    }
}
impl S1 {
    #[inline]
    pub fn new_bitfield_1() -> u32 {
        0
    }
}

Expected Results

No layout test failures.

@fitzgen
Copy link
Member

fitzgen commented Oct 11, 2017

Looks like our bitfield unit allocation is off. This probably should be two units: one u16 and one u8. And then they should be packed to alignment of 1 (which I don't understand why from the definition...).

@pepyakin
Copy link
Contributor Author

This is somehow related to the fact that the bitfields are unnamed.

Consider this snippet. It will return 3 for size and 1 for alignment. But if you give a name to either field, both size and align will return 4.

@fitzgen
Copy link
Member

fitzgen commented Oct 12, 2017

I guess anonymous bitfields only contribute to size, not alignment? Intuitively, that makes sense because they can never be read, so unaligned reads are a non-issue.

At this point, I think we really need to go through the ABI's text and carefully translate the algorithms described therein...

fitzgen added a commit to fitzgen/rust-bindgen that referenced this issue Oct 25, 2017
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

2 participants