Skip to content

Commit 5785340

Browse files
tbodtemilio
authored andcommitted
Don't generate 2^64 byte padding fields on unions
The --explicit-padding flag would make bindgen try to add tail padding to rust unions, by adding up the size of all the union fields and subtracting from the size of the union as given by clang. The total size of a union's fields is always larger than the union, so the subtraction underflowed and bindgen produced padding fields larger than addressable RAM.
1 parent 9738fb9 commit 5785340

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

src/codegen/struct_layout.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ impl<'a> StructLayoutTracker<'a> {
279279
return None;
280280
}
281281

282+
// Padding doesn't make sense for rust unions.
283+
if self.is_rust_union {
284+
return None;
285+
}
286+
282287
if self.latest_offset == comp_layout.size {
283288
// This struct does not contain tail padding.
284289
return None;

tests/expectations/tests/explicit-padding.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,68 @@ fn bindgen_test_layout_pad_me() {
6363
)
6464
);
6565
}
66+
#[repr(C)]
67+
#[derive(Copy, Clone)]
68+
pub union dont_pad_me {
69+
pub first: u8,
70+
pub second: u32,
71+
pub third: u16,
72+
}
73+
#[test]
74+
fn bindgen_test_layout_dont_pad_me() {
75+
assert_eq!(
76+
::std::mem::size_of::<dont_pad_me>(),
77+
4usize,
78+
concat!("Size of: ", stringify!(dont_pad_me))
79+
);
80+
assert_eq!(
81+
::std::mem::align_of::<dont_pad_me>(),
82+
4usize,
83+
concat!("Alignment of ", stringify!(dont_pad_me))
84+
);
85+
assert_eq!(
86+
unsafe {
87+
&(*(::std::ptr::null::<dont_pad_me>())).first as *const _ as usize
88+
},
89+
0usize,
90+
concat!(
91+
"Offset of field: ",
92+
stringify!(dont_pad_me),
93+
"::",
94+
stringify!(first)
95+
)
96+
);
97+
assert_eq!(
98+
unsafe {
99+
&(*(::std::ptr::null::<dont_pad_me>())).second as *const _ as usize
100+
},
101+
0usize,
102+
concat!(
103+
"Offset of field: ",
104+
stringify!(dont_pad_me),
105+
"::",
106+
stringify!(second)
107+
)
108+
);
109+
assert_eq!(
110+
unsafe {
111+
&(*(::std::ptr::null::<dont_pad_me>())).third as *const _ as usize
112+
},
113+
0usize,
114+
concat!(
115+
"Offset of field: ",
116+
stringify!(dont_pad_me),
117+
"::",
118+
stringify!(third)
119+
)
120+
);
121+
}
122+
impl Default for dont_pad_me {
123+
fn default() -> Self {
124+
let mut s = ::std::mem::MaybeUninit::<Self>::uninit();
125+
unsafe {
126+
::std::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
127+
s.assume_init()
128+
}
129+
}
130+
}

tests/headers/explicit-padding.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ struct pad_me {
99
uint32_t second;
1010
uint16_t third;
1111
};
12+
13+
union dont_pad_me {
14+
uint8_t first;
15+
uint32_t second;
16+
uint16_t third;
17+
};

0 commit comments

Comments
 (0)