summaryrefslogtreecommitdiff
path: root/src/codegen/mod.rs
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2017-03-03 03:39:06 +0100
committerEmilio Cobos Álvarez <emilio@crisal.io>2017-03-06 19:24:43 +0100
commit5982cd3dc3a4f356131f6c10939d3890f0c05e22 (patch)
treecc2470853c7c7d9f8f47d2f669c4e205fd4f17b8 /src/codegen/mod.rs
parent17275f87004044d8702a80467880f568738357c2 (diff)
codegen: Don't assume unsized structs have address.
Per C semantics, they may not.
Diffstat (limited to 'src/codegen/mod.rs')
-rw-r--r--src/codegen/mod.rs22
1 files changed, 15 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.