Skip to content

Commit b9550bd

Browse files
authored
Merge pull request #1313 from google/bitfieldthing
Explicitly reject bitfields
2 parents fdfb26e + 748119f commit b9550bd

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

engine/src/conversion/analysis/pod/byvalue_checker.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ impl ByValueChecker {
158158
));
159159
break;
160160
}
161+
None if ty_id.get_final_item() == "__BindgenBitfieldUnit" => {
162+
field_safety_problem = PodState::UnsafeToBePod(format!(
163+
"Type {tyname} could not be POD because it is a bitfield"
164+
));
165+
break;
166+
}
161167
None => {
162168
field_safety_problem = PodState::UnsafeToBePod(format!(
163169
"Type {tyname} could not be POD because its dependent type {ty_id} isn't known"

engine/src/types.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ impl std::fmt::Debug for QualifiedName {
236236
/// cxx.
237237
#[derive(Error, Clone, Debug)]
238238
pub enum InvalidIdentError {
239+
#[error("Union are not supported by autocxx (and their bindgen names have __ so are not acceptable to cxx)")]
240+
Union,
241+
#[error("Bitfields are not supported by autocxx (and their bindgen names have __ so are not acceptable to cxx)")]
242+
Bitfield,
239243
#[error("Names containing __ are reserved by C++ so not acceptable to cxx")]
240244
TooManyUnderscores,
241245
#[error("bindgen decided to call this type _bindgen_ty_N because it couldn't deduce the correct name for it. That means we can't generate C++ bindings to it.")]
@@ -251,7 +255,12 @@ pub enum InvalidIdentError {
251255
/// where code will be output as part of the `#[cxx::bridge]` mod.
252256
pub fn validate_ident_ok_for_cxx(id: &str) -> Result<(), InvalidIdentError> {
253257
validate_ident_ok_for_rust(id)?;
254-
if id.contains("__") {
258+
// Provide a couple of more specific diagnostics if we can.
259+
if id.starts_with("__BindgenBitfieldUnit") {
260+
Err(InvalidIdentError::Bitfield)
261+
} else if id.starts_with("__BindgenUnionField") {
262+
Err(InvalidIdentError::Union)
263+
} else if id.contains("__") {
255264
Err(InvalidIdentError::TooManyUnderscores)
256265
} else if id.starts_with("_bindgen_ty_") {
257266
Err(InvalidIdentError::BindgenTy)

integration-tests/tests/integration_test.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12241,6 +12241,45 @@ fn test_ignore_va_list() {
1224112241
run_test("", hdr, rs, &["A"], &[]);
1224212242
}
1224312243

12244+
#[test]
12245+
fn test_cpp_union_pod() {
12246+
let hdr = indoc! {"
12247+
typedef unsigned long long UInt64_t;
12248+
struct ManagedPtr_t_;
12249+
typedef struct ManagedPtr_t_ ManagedPtr_t;
12250+
12251+
typedef int (*ManagedPtr_ManagerFunction_t)(
12252+
ManagedPtr_t *managedPtr,
12253+
const ManagedPtr_t *srcPtr,
12254+
int operation);
12255+
12256+
typedef union {
12257+
int intValue;
12258+
void *ptr;
12259+
} ManagedPtr_t_data_;
12260+
12261+
struct ManagedPtr_t_ {
12262+
void *pointer;
12263+
ManagedPtr_t_data_ userData[4];
12264+
ManagedPtr_ManagerFunction_t manager;
12265+
};
12266+
12267+
typedef struct CorrelationId_t_ {
12268+
unsigned int size : 8;
12269+
unsigned int valueType : 4;
12270+
unsigned int classId : 16;
12271+
unsigned int reserved : 4;
12272+
12273+
union {
12274+
UInt64_t intValue;
12275+
ManagedPtr_t ptrValue;
12276+
} value;
12277+
} CorrelationId_t;
12278+
"};
12279+
run_test("", hdr, quote! {}, &["CorrelationId_t_"], &[]);
12280+
run_test_expect_fail("", hdr, quote! {}, &[], &["CorrelationId_t_"]);
12281+
}
12282+
1224412283
// Yet to test:
1224512284
// - Ifdef
1224612285
// - Out param pointers

0 commit comments

Comments
 (0)