diff options
author | Nick Fitzgerald <fitzgen@gmail.com> | 2017-11-01 15:57:50 -0700 |
---|---|---|
committer | Nick Fitzgerald <fitzgen@gmail.com> | 2017-11-01 16:17:01 -0700 |
commit | 8592f3677b7d9624ac6bd64df46a962c92b4561f (patch) | |
tree | d969538f9276d9860f7ad7d2528629e49bfeaefd | |
parent | ddb680b27db6581070b7b4fb03ea1119167a0bd3 (diff) |
Avoid divide-by-zero when checking if a field will merge with bitfields
-rw-r--r-- | src/codegen/struct_layout.rs | 7 | ||||
-rw-r--r-- | tests/expectations/tests/divide-by-zero-in-struct-layout.rs | 45 | ||||
-rw-r--r-- | tests/headers/divide-by-zero-in-struct-layout.h | 22 |
3 files changed, 72 insertions, 2 deletions
diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index c3c781cb..ca46947d 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -335,9 +335,12 @@ impl<'a> StructLayoutTracker<'a> { new_field_layout ); + // Avoid divide-by-zero errors if align is 0. + let align = cmp::max(1, layout.align); + if self.last_field_was_bitfield && - new_field_layout.align <= layout.size % layout.align && - new_field_layout.size <= layout.size % layout.align + new_field_layout.align <= layout.size % align && + new_field_layout.size <= layout.size % align { // The new field will be coalesced into some of the remaining bits. // diff --git a/tests/expectations/tests/divide-by-zero-in-struct-layout.rs b/tests/expectations/tests/divide-by-zero-in-struct-layout.rs new file mode 100644 index 00000000..9fb429af --- /dev/null +++ b/tests/expectations/tests/divide-by-zero-in-struct-layout.rs @@ -0,0 +1,45 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] + + +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct WithBitfield { + pub _bitfield_1: [u8; 0usize], + pub __bindgen_padding_0: u32, + pub a: ::std::os::raw::c_uint, +} +impl WithBitfield { + #[inline] + pub fn new_bitfield_1() -> u8 { + 0 + } +} +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct WithBitfieldAndAttrPacked { + pub _bitfield_1: [u8; 0usize], + pub a: ::std::os::raw::c_uint, + pub __bindgen_padding_0: u8, +} +impl WithBitfieldAndAttrPacked { + #[inline] + pub fn new_bitfield_1() -> u8 { + 0 + } +} +#[repr(C, packed)] +#[derive(Debug, Default, Copy, Clone)] +pub struct WithBitfieldAndPacked { + pub _bitfield_1: [u8; 0usize], + pub a: ::std::os::raw::c_uint, + pub __bindgen_padding_0: u8, +} +impl WithBitfieldAndPacked { + #[inline] + pub fn new_bitfield_1() -> u8 { + 0 + } +} diff --git a/tests/headers/divide-by-zero-in-struct-layout.h b/tests/headers/divide-by-zero-in-struct-layout.h new file mode 100644 index 00000000..470250d3 --- /dev/null +++ b/tests/headers/divide-by-zero-in-struct-layout.h @@ -0,0 +1,22 @@ +// bindgen-flags: --no-layout-tests +// +// Unfortunately, we aren't translating the second and third structs correctly +// yet. But we definitely shouldn't divide-by-zero when we see it... +// +// Once we fix #981 we should remove the `--no-layout-tests`. + +struct WithBitfield { + unsigned : 7; + unsigned a; +}; + +struct WithBitfieldAndAttrPacked { + unsigned : 7; + unsigned a; +} __attribute__((packed)); + +#pragma pack(1) +struct WithBitfieldAndPacked { + unsigned : 7; + unsigned a; +}; |