Skip to content

Struct typedef in class fails with wrong struct size #639

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

Closed
drewkett opened this issue Apr 17, 2017 · 1 comment
Closed

Struct typedef in class fails with wrong struct size #639

drewkett opened this issue Apr 17, 2017 · 1 comment

Comments

@drewkett
Copy link

Input C/C++ Header

class Foo {
    public:
    typedef struct {
        int abc;
    } Bar;

    Bar bar;
};

Bindgen Invokation

$ bindgen input.h -- -x c++

Actual Results

ERROR:bindgen::codegen::struct_layout: Calculated wrong layout for Foo, too more 4 bytes
/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Debug, Copy)]
pub struct Foo {
    pub __bindgen_anon_1: Foo_Bar,
    pub bar: Foo_Bar,
}
#[repr(C)]
#[derive(Debug, Copy)]
pub struct Foo_Bar {
    pub abc: ::std::os::raw::c_int,
}
#[test]
fn bindgen_test_layout_Foo_Bar() {
    assert_eq!(::std::mem::size_of::<Foo_Bar>() , 4usize , concat ! (
               "Size of: " , stringify ! ( Foo_Bar ) ));
    assert_eq! (::std::mem::align_of::<Foo_Bar>() , 4usize , concat ! (
                "Alignment of " , stringify ! ( Foo_Bar ) ));
    assert_eq! (unsafe {
                & ( * ( 0 as * const Foo_Bar ) ) . abc as * const _ as usize }
                , 0usize , concat ! (
                "Alignment of field: " , stringify ! ( Foo_Bar ) , "::" ,
                stringify ! ( abc ) ));
}
impl Clone for Foo_Bar {
    fn clone(&self) -> Self { *self }
}
#[test]
fn bindgen_test_layout_Foo() {
    assert_eq!(::std::mem::size_of::<Foo>() , 4usize , concat ! (
               "Size of: " , stringify ! ( Foo ) ));
    assert_eq! (::std::mem::align_of::<Foo>() , 4usize , concat ! (
                "Alignment of " , stringify ! ( Foo ) ));
    assert_eq! (unsafe {
                & ( * ( 0 as * const Foo ) ) . bar as * const _ as usize } ,
                0usize , concat ! (
                "Alignment of field: " , stringify ! ( Foo ) , "::" ,
                stringify ! ( bar ) ));
}
impl Clone for Foo {
    fn clone(&self) -> Self { *self }
}

Expected Results

The struct typedef shouldn't be a member of the Foo struct.

@fitzgen
Copy link
Member

fitzgen commented Apr 17, 2017

Thanks for the bug report!

Looks like our anonymous field code is getting tripped up, and we're ending up with two Bar members:

pub struct Foo {
    pub __bindgen_anon_1: Foo_Bar,
    pub bar: Foo_Bar,
}

Kowasaki pushed a commit to Kowasaki/rust-bindgen that referenced this issue May 2, 2017
They appear later in the clang AST, so we need to check for them as a
special-case before flushing the new field.

Fixes rust-lang#639
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