Skip to content

Commit ec78ed6

Browse files
committed
codegen: Don't assume unsized structs have address.
Per C semantics, they may not.
1 parent 4c07a72 commit ec78ed6

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

src/codegen/mod.rs

+18-7
Original file line numberDiff line numberDiff line change
@@ -1284,17 +1284,28 @@ impl CodeGenerator for CompInfo {
12841284
}
12851285
}
12861286

1287-
// C requires every struct to be addressable, so what C compilers do is
1288-
// making the struct 1-byte sized.
1287+
// C++ requires every struct to be addressable, so what C++ compilers do
1288+
// is making the struct 1-byte sized.
1289+
//
1290+
// This is apparently not the case for C, see:
1291+
// https://github.com/servo/rust-bindgen/issues/551
1292+
//
1293+
// Just get the layout, and assume C++ if not.
12891294
//
12901295
// NOTE: This check is conveniently here to avoid the dummy fields we
12911296
// may add for unused template parameters.
12921297
if self.is_unsized(ctx) {
1293-
let ty = BlobTyBuilder::new(Layout::new(1, 1)).build();
1294-
let field = StructFieldBuilder::named("_address")
1295-
.pub_()
1296-
.build_ty(ty);
1297-
fields.push(field);
1298+
let has_address = match layout {
1299+
Some(l) => l.size != 0,
1300+
None => true,
1301+
};
1302+
if has_address {
1303+
let ty = BlobTyBuilder::new(Layout::new(1, 1)).build();
1304+
let field = StructFieldBuilder::named("_address")
1305+
.pub_()
1306+
.build_ty(ty);
1307+
fields.push(field);
1308+
}
12981309
}
12991310

13001311
// Append any extra template arguments that nobody has used so far.
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(non_snake_case)]
5+
6+
7+
#[repr(C)]
8+
#[derive(Debug, Default, Copy)]
9+
pub struct Foo {
10+
}
11+
#[test]
12+
fn bindgen_test_layout_Foo() {
13+
assert_eq!(::std::mem::size_of::<Foo>() , 0usize , concat ! (
14+
"Size of: " , stringify ! ( Foo ) ));
15+
assert_eq! (::std::mem::align_of::<Foo>() , 1usize , concat ! (
16+
"Alignment of " , stringify ! ( Foo ) ));
17+
}
18+
impl Clone for Foo {
19+
fn clone(&self) -> Self { *self }
20+
}

tests/headers/c-empty-layout.h

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
struct Foo {};

0 commit comments

Comments
 (0)