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

Wrong layout for empty struct in C mode #551

Closed
Dushistov opened this issue Mar 2, 2017 · 3 comments
Closed

Wrong layout for empty struct in C mode #551

Dushistov opened this issue Mar 2, 2017 · 3 comments
Labels

Comments

@Dushistov
Copy link
Contributor

Input C/C++ Header

struct Foo {};
typedef union jvalue {
    unsigned char z;
    struct Foo *p;
} jvalue;
$ bindgen --no-unstable-rust input.h

Actual Results

cargo test report failure:

test bindgen_test_layout_Foo ... FAILED

failures:

---- bindgen_test_layout_Foo stdout ----
        thread 'bindgen_test_layout_Foo' panicked at 'assertion failed: `(left == right)` (left: `1`, right: `0`): Size of: Foo', lib.rs:34
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Expected Results

generated tests should all be green

Note

In the real example (not reduced one as above) cargo test failed in another place,
here real example (with resolved typedefs) from windows variant of java sdk:

struct _jobject {};
typedef struct _jobject *jobject;

typedef union jvalue {
    unsigned char z;
    signed char    b;
    unsigned short    c;
    short   s;
    long     i;
  __int64    j;
  float   f;
  double  d;
  jobject  l;
} jvalue;
@emilio
Copy link
Contributor

emilio commented Mar 3, 2017

Oh, interesting, so this is one of these C vs. C++ semantics I guess:

The same:

// test.h
struct Foo {};
$ ./target/debug/bindgen test.h -- -x c++                                                                                                                                                  
/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Debug, Copy)]
pub struct Foo {
    pub _address: u8,
}
#[test]
fn bindgen_test_layout_Foo() {
    assert_eq!(::std::mem::size_of::<Foo>() , 1usize , concat ! (
               "Size of: " , stringify ! ( Foo ) ));
    assert_eq! (::std::mem::align_of::<Foo>() , 1usize , concat ! (
                "Alignment of " , stringify ! ( Foo ) ));
}
impl Clone for Foo {
    fn clone(&self) -> Self { *self }
}

$ ./target/debug/bindgen test.h                                                                                                                                                            
/* automatically generated by rust-bindgen */

#[repr(C)]
#[derive(Debug, Copy)]
pub struct Foo {
    pub _address: u8,
}
#[test]
fn bindgen_test_layout_Foo() {
    assert_eq!(::std::mem::size_of::<Foo>() , 0usize , concat ! (
               "Size of: " , stringify ! ( Foo ) ));
    assert_eq! (::std::mem::align_of::<Foo>() , 1usize , concat ! (
                "Alignment of " , stringify ! ( Foo ) ));
}
impl Clone for Foo {
    fn clone(&self) -> Self { *self }
}

That different 1 or 0 is what clang tells us the size of that struct is.

So it seems in C++ all structs are addressable, but not in C.

// test.c
#include <stdio.h>

struct Foo {};

struct Bar {
  struct Foo f;
};

int main() {
  struct Bar b;
  struct Foo f;
  printf("%lu, %lu %p, %p\n", sizeof(struct Bar), sizeof(struct Foo), &b, &f);
  return 0;
}
$ cc test.c
$ ./a.out
0, 0 0x7ffe8ffb10b0, 0x7ffe8ffb10b0
$ c++ test.c -x c++
$ ./a.out
1, 1 0x7ffefd7a8faf, 0x7ffefd7a8fae

Bindgen is usually agnostic to the header and just trusts clang. perhaps we should do the same check here to avoid generating the _address field.

@emilio emilio changed the title wrong test with no-unstable-rust Wrong layout for empty struct in C mode Mar 3, 2017
@emilio emilio added the bug label Mar 3, 2017
@emilio
Copy link
Contributor

emilio commented Mar 3, 2017

Edited the description to be more meaningful. Patch at #552.

Dushistov added a commit to Dushistov/flapigen-rs that referenced this issue Mar 3, 2017
@emilio
Copy link
Contributor

emilio commented Mar 12, 2017

This should be fixed now.

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

No branches or pull requests

2 participants