summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/comp.rs2
-rw-r--r--tests/expectations/tests/union_bitfield.rs185
-rw-r--r--tests/headers/union_bitfield.h10
3 files changed, 196 insertions, 1 deletions
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 230ba5b4..7320015f 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -1498,7 +1498,7 @@ impl CompInfo {
Field::DataMember(ref field_data) => {
field_data.ty().can_derive_copy(ctx)
}
- Field::Bitfields(_) => false,
+ Field::Bitfields(_) => true,
})
}
}
diff --git a/tests/expectations/tests/union_bitfield.rs b/tests/expectations/tests/union_bitfield.rs
new file mode 100644
index 00000000..c67557ef
--- /dev/null
+++ b/tests/expectations/tests/union_bitfield.rs
@@ -0,0 +1,185 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Copy)]
+pub union U4 {
+ pub _bitfield_1: u8,
+ _bindgen_union_align: u32,
+}
+#[test]
+fn bindgen_test_layout_U4() {
+ assert_eq!(
+ ::std::mem::size_of::<U4>(),
+ 4usize,
+ concat!("Size of: ", stringify!(U4))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<U4>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(U4))
+ );
+}
+impl Clone for U4 {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for U4 {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+impl U4 {
+ #[inline]
+ pub fn derp(&self) -> ::std::os::raw::c_uint {
+ let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &self._bitfield_1 as *const _ as *const u8,
+ &mut unit_field_val as *mut u8 as *mut u8,
+ ::std::mem::size_of::<u8>(),
+ )
+ };
+ let mask = 1u64 as u8;
+ let val = (unit_field_val & mask) >> 0usize;
+ unsafe { ::std::mem::transmute(val as u32) }
+ }
+ #[inline]
+ pub fn set_derp(&mut self, val: ::std::os::raw::c_uint) {
+ let mask = 1u64 as u8;
+ let val = val as u32 as u8;
+ let mut unit_field_val: u8 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &self._bitfield_1 as *const _ as *const u8,
+ &mut unit_field_val as *mut u8 as *mut u8,
+ ::std::mem::size_of::<u8>(),
+ )
+ };
+ unit_field_val &= !mask;
+ unit_field_val |= (val << 0usize) & mask;
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &unit_field_val as *const _ as *const u8,
+ &mut self._bitfield_1 as *mut _ as *mut u8,
+ ::std::mem::size_of::<u8>(),
+ );
+ }
+ }
+ #[inline]
+ pub fn new_bitfield_1(derp: ::std::os::raw::c_uint) -> u8 {
+ (0 | ((derp as u32 as u8) << 0usize) & (1u64 as u8))
+ }
+}
+#[repr(C)]
+#[derive(Copy)]
+pub union B {
+ pub _bitfield_1: u32,
+ _bindgen_union_align: u32,
+}
+#[test]
+fn bindgen_test_layout_B() {
+ assert_eq!(
+ ::std::mem::size_of::<B>(),
+ 4usize,
+ concat!("Size of: ", stringify!(B))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<B>(),
+ 4usize,
+ concat!("Alignment of ", stringify!(B))
+ );
+}
+impl Clone for B {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl Default for B {
+ fn default() -> Self {
+ unsafe { ::std::mem::zeroed() }
+ }
+}
+impl B {
+ #[inline]
+ pub fn foo(&self) -> ::std::os::raw::c_uint {
+ let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &self._bitfield_1 as *const _ as *const u8,
+ &mut unit_field_val as *mut u32 as *mut u8,
+ ::std::mem::size_of::<u32>(),
+ )
+ };
+ let mask = 2147483647u64 as u32;
+ let val = (unit_field_val & mask) >> 0usize;
+ unsafe { ::std::mem::transmute(val as u32) }
+ }
+ #[inline]
+ pub fn set_foo(&mut self, val: ::std::os::raw::c_uint) {
+ let mask = 2147483647u64 as u32;
+ let val = val as u32 as u32;
+ let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &self._bitfield_1 as *const _ as *const u8,
+ &mut unit_field_val as *mut u32 as *mut u8,
+ ::std::mem::size_of::<u32>(),
+ )
+ };
+ unit_field_val &= !mask;
+ unit_field_val |= (val << 0usize) & mask;
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &unit_field_val as *const _ as *const u8,
+ &mut self._bitfield_1 as *mut _ as *mut u8,
+ ::std::mem::size_of::<u32>(),
+ );
+ }
+ }
+ #[inline]
+ pub fn bar(&self) -> ::std::os::raw::c_uchar {
+ let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &self._bitfield_1 as *const _ as *const u8,
+ &mut unit_field_val as *mut u32 as *mut u8,
+ ::std::mem::size_of::<u32>(),
+ )
+ };
+ let mask = 2147483648u64 as u32;
+ let val = (unit_field_val & mask) >> 31usize;
+ unsafe { ::std::mem::transmute(val as u8) }
+ }
+ #[inline]
+ pub fn set_bar(&mut self, val: ::std::os::raw::c_uchar) {
+ let mask = 2147483648u64 as u32;
+ let val = val as u8 as u32;
+ let mut unit_field_val: u32 = unsafe { ::std::mem::uninitialized() };
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &self._bitfield_1 as *const _ as *const u8,
+ &mut unit_field_val as *mut u32 as *mut u8,
+ ::std::mem::size_of::<u32>(),
+ )
+ };
+ unit_field_val &= !mask;
+ unit_field_val |= (val << 31usize) & mask;
+ unsafe {
+ ::std::ptr::copy_nonoverlapping(
+ &unit_field_val as *const _ as *const u8,
+ &mut self._bitfield_1 as *mut _ as *mut u8,
+ ::std::mem::size_of::<u32>(),
+ );
+ }
+ }
+ #[inline]
+ pub fn new_bitfield_1(foo: ::std::os::raw::c_uint, bar: ::std::os::raw::c_uchar) -> u32 {
+ ((0 | ((foo as u32 as u32) << 0usize) & (2147483647u64 as u32))
+ | ((bar as u8 as u32) << 31usize) & (2147483648u64 as u32))
+ }
+}
diff --git a/tests/headers/union_bitfield.h b/tests/headers/union_bitfield.h
new file mode 100644
index 00000000..99072957
--- /dev/null
+++ b/tests/headers/union_bitfield.h
@@ -0,0 +1,10 @@
+// bindgen-flags: --with-derive-hash --with-derive-partialeq --with-derive-eq --impl-partialeq
+
+union U4 {
+ unsigned derp : 1;
+};
+
+union B {
+ unsigned foo : 31;
+ unsigned char bar : 1;
+};