From 238e9ac3a74031551d2398fe32d0ec30d30ef14f Mon Sep 17 00:00:00 2001 From: Thomas Hebb Date: Mon, 17 Mar 2025 18:38:03 -0400 Subject: [PATCH] Don't wrap struct padding in __bindgen_marker_Opaque Just as with zero-sized structs, this usage of blob() doesn't mean the type is opaque: padding is perfectly safe to allocate, modify, and pass around. By marking it with __bindgen_marker_Opaque, we prevent autocxx from making padded structs POD. This hasn't cropped up so far because explicit padding fields are quite rare in bindgen, but they do show up when a struct ends with a bitfield. I'm about to contribute POD bitfield support to autocxx, which this fix helps enable. --- bindgen/codegen/mod.rs | 9 +++------ bindgen/codegen/struct_layout.rs | 7 ++++++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index 998c4ca2da..d2e95ca373 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -2362,12 +2362,9 @@ impl CodeGenerator for CompInfo { if has_address { let layout = Layout::new(1, 1); - // Normally for opaque data we use helpers::blob, - // which may wrap it in __bindgen_marker_Opaque. - // Downstream tools may then use this as a sign that - // the type is complex or can't be stack-allocated, - // etc. But in this case this one-byte field is harmless - // so we'll just represent it without that extra marker. + // Don't use __bindgen_marker_Opaque for this harmless one-byte + // field. See StructLayoutTracker::padding_field() for a longer + // explanation of blob_inner() vs blob(). let ty = helpers::blob_inner(ctx, Layout::new(1, 1), false); struct_layout.saw_field_with_layout( "_address", diff --git a/bindgen/codegen/struct_layout.rs b/bindgen/codegen/struct_layout.rs index f7f66373fb..94f164fbd2 100644 --- a/bindgen/codegen/struct_layout.rs +++ b/bindgen/codegen/struct_layout.rs @@ -393,7 +393,12 @@ impl<'a> StructLayoutTracker<'a> { } fn padding_field(&mut self, layout: Layout) -> proc_macro2::TokenStream { - let ty = helpers::blob(self.ctx, layout, false); + // Normally for opaque data we use helpers::blob(), which may wrap it + // __bindgen_marker_Opaque. Downstream tools may then use this as a + // sign that the type is complex or can't be stack-allocated, etc. But + // in this case the padding is just plain data, so we want to represent + // it without the extra marker. + let ty = helpers::blob_inner(self.ctx, layout, false); let padding_count = self.padding_count; self.padding_count += 1;