summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/mod.rs22
-rw-r--r--tests/expectations/tests/c-empty-layout.rs20
-rw-r--r--tests/expectations/tests/cpp-empty-layout.rs21
-rw-r--r--tests/headers/c-empty-layout.h1
-rw-r--r--tests/headers/cpp-empty-layout.hpp1
5 files changed, 58 insertions, 7 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 77941fa3..99324bc6 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -1286,17 +1286,25 @@ impl CodeGenerator for CompInfo {
}
}
- // C requires every struct to be addressable, so what C compilers do is
- // making the struct 1-byte sized.
+ // C++ requires every struct to be addressable, so what C++ compilers do
+ // is making the struct 1-byte sized.
+ //
+ // This is apparently not the case for C, see:
+ // https://github.com/servo/rust-bindgen/issues/551
+ //
+ // Just get the layout, and assume C++ if not.
//
// NOTE: This check is conveniently here to avoid the dummy fields we
// may add for unused template parameters.
if self.is_unsized(ctx) {
- let ty = BlobTyBuilder::new(Layout::new(1, 1)).build();
- let field = StructFieldBuilder::named("_address")
- .pub_()
- .build_ty(ty);
- fields.push(field);
+ let has_address = layout.map_or(true, |l| l.size != 0);
+ if has_address {
+ let ty = BlobTyBuilder::new(Layout::new(1, 1)).build();
+ let field = StructFieldBuilder::named("_address")
+ .pub_()
+ .build_ty(ty);
+ fields.push(field);
+ }
}
// Append any extra template arguments that nobody has used so far.
diff --git a/tests/expectations/tests/c-empty-layout.rs b/tests/expectations/tests/c-empty-layout.rs
new file mode 100644
index 00000000..7dc16d48
--- /dev/null
+++ b/tests/expectations/tests/c-empty-layout.rs
@@ -0,0 +1,20 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct Foo {
+}
+#[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 }
+}
diff --git a/tests/expectations/tests/cpp-empty-layout.rs b/tests/expectations/tests/cpp-empty-layout.rs
new file mode 100644
index 00000000..fbeb3d5e
--- /dev/null
+++ b/tests/expectations/tests/cpp-empty-layout.rs
@@ -0,0 +1,21 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+#[repr(C)]
+#[derive(Debug, Default, 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 }
+}
diff --git a/tests/headers/c-empty-layout.h b/tests/headers/c-empty-layout.h
new file mode 100644
index 00000000..1fe02e89
--- /dev/null
+++ b/tests/headers/c-empty-layout.h
@@ -0,0 +1 @@
+struct Foo {};
diff --git a/tests/headers/cpp-empty-layout.hpp b/tests/headers/cpp-empty-layout.hpp
new file mode 100644
index 00000000..1fe02e89
--- /dev/null
+++ b/tests/headers/cpp-empty-layout.hpp
@@ -0,0 +1 @@
+struct Foo {};