Skip to content

Commit c7bf200

Browse files
committed
codegen: Make zero-sized arrays affect alignment.
Fixes #684
1 parent fbb8420 commit c7bf200

10 files changed

+141
-41
lines changed

src/codegen/mod.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -3740,14 +3740,14 @@ mod utils {
37403740
#[repr(C)]
37413741
#[derive(Default)]
37423742
pub struct __IncompleteArrayField<T>(
3743-
::#prefix::marker::PhantomData<T>);
3743+
::#prefix::marker::PhantomData<T>, [T; 0]);
37443744
};
37453745

37463746
let incomplete_array_impl = quote! {
37473747
impl<T> __IncompleteArrayField<T> {
37483748
#[inline]
37493749
pub fn new() -> Self {
3750-
__IncompleteArrayField(::#prefix::marker::PhantomData)
3750+
__IncompleteArrayField(::#prefix::marker::PhantomData, [])
37513751
}
37523752

37533753
#[inline]
@@ -3790,15 +3790,10 @@ mod utils {
37903790
}
37913791
};
37923792

3793-
let incomplete_array_copy_impl = quote! {
3794-
impl<T> ::#prefix::marker::Copy for __IncompleteArrayField<T> {}
3795-
};
3796-
37973793
let items = vec![incomplete_array_decl,
37983794
incomplete_array_impl,
37993795
incomplete_array_debug_impl,
3800-
incomplete_array_clone_impl,
3801-
incomplete_array_copy_impl];
3796+
incomplete_array_clone_impl];
38023797

38033798
let old_items = mem::replace(result, items);
38043799
result.extend(old_items.into_iter());

tests/expectations/tests/class.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
/* automatically generated by rust-bindgen */
22

3-
4-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
5-
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
69

710
#[repr(C)]
811
#[derive(Default)]
9-
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
12+
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
1013
impl<T> __IncompleteArrayField<T> {
1114
#[inline]
1215
pub fn new() -> Self {
13-
__IncompleteArrayField(::std::marker::PhantomData)
16+
__IncompleteArrayField(::std::marker::PhantomData, [])
1417
}
1518
#[inline]
1619
pub unsafe fn as_ptr(&self) -> *const T {
@@ -40,7 +43,6 @@ impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
4043
Self::new()
4144
}
4245
}
43-
impl<T> ::std::marker::Copy for __IncompleteArrayField<T> {}
4446
#[repr(C)]
4547
#[derive(Copy, Clone)]
4648
pub struct C {

tests/expectations/tests/class_1_0.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
/* automatically generated by rust-bindgen */
22

3-
4-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
5-
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
69

710
#[repr(C)]
811
#[derive(Default)]
9-
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
12+
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
1013
impl<T> __IncompleteArrayField<T> {
1114
#[inline]
1215
pub fn new() -> Self {
13-
__IncompleteArrayField(::std::marker::PhantomData)
16+
__IncompleteArrayField(::std::marker::PhantomData, [])
1417
}
1518
#[inline]
1619
pub unsafe fn as_ptr(&self) -> *const T {
@@ -40,7 +43,6 @@ impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
4043
Self::new()
4144
}
4245
}
43-
impl<T> ::std::marker::Copy for __IncompleteArrayField<T> {}
4446
#[repr(C)]
4547
pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
4648
impl<T> __BindgenUnionField<T> {

tests/expectations/tests/derive-hash-struct-with-incomplete-array.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
/* automatically generated by rust-bindgen */
22

3-
4-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
5-
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
69

710
#[repr(C)]
811
#[derive(Default)]
9-
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
12+
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
1013
impl<T> __IncompleteArrayField<T> {
1114
#[inline]
1215
pub fn new() -> Self {
13-
__IncompleteArrayField(::std::marker::PhantomData)
16+
__IncompleteArrayField(::std::marker::PhantomData, [])
1417
}
1518
#[inline]
1619
pub unsafe fn as_ptr(&self) -> *const T {
@@ -40,7 +43,6 @@ impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
4043
Self::new()
4144
}
4245
}
43-
impl<T> ::std::marker::Copy for __IncompleteArrayField<T> {}
4446
#[repr(C)]
4547
#[derive(Debug, Default)]
4648
pub struct test {

tests/expectations/tests/issue-643-inner-struct.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
/* automatically generated by rust-bindgen */
22

3-
4-
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
5-
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
69

710
#[repr(C)]
811
#[derive(Default)]
9-
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
12+
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
1013
impl<T> __IncompleteArrayField<T> {
1114
#[inline]
1215
pub fn new() -> Self {
13-
__IncompleteArrayField(::std::marker::PhantomData)
16+
__IncompleteArrayField(::std::marker::PhantomData, [])
1417
}
1518
#[inline]
1619
pub unsafe fn as_ptr(&self) -> *const T {
@@ -40,7 +43,6 @@ impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
4043
Self::new()
4144
}
4245
}
43-
impl<T> ::std::marker::Copy for __IncompleteArrayField<T> {}
4446
#[repr(C)]
4547
#[derive(Debug)]
4648
pub struct rte_ring {

tests/expectations/tests/layout_align.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@ where
9191
}
9292
#[repr(C)]
9393
#[derive(Default)]
94-
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
94+
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
9595
impl<T> __IncompleteArrayField<T> {
9696
#[inline]
9797
pub fn new() -> Self {
98-
__IncompleteArrayField(::std::marker::PhantomData)
98+
__IncompleteArrayField(::std::marker::PhantomData, [])
9999
}
100100
#[inline]
101101
pub unsafe fn as_ptr(&self) -> *const T {
@@ -125,7 +125,6 @@ impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
125125
Self::new()
126126
}
127127
}
128-
impl<T> ::std::marker::Copy for __IncompleteArrayField<T> {}
129128
#[repr(C)]
130129
#[derive(Debug)]
131130
pub struct rte_kni_fifo {

tests/expectations/tests/layout_large_align_field.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99

1010
#[repr(C)]
1111
#[derive(Default)]
12-
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
12+
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
1313
impl<T> __IncompleteArrayField<T> {
1414
#[inline]
1515
pub fn new() -> Self {
16-
__IncompleteArrayField(::std::marker::PhantomData)
16+
__IncompleteArrayField(::std::marker::PhantomData, [])
1717
}
1818
#[inline]
1919
pub unsafe fn as_ptr(&self) -> *const T {
@@ -43,7 +43,6 @@ impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
4343
Self::new()
4444
}
4545
}
46-
impl<T> ::std::marker::Copy for __IncompleteArrayField<T> {}
4746
pub const RTE_CACHE_LINE_SIZE: u32 = 64;
4847
pub const RTE_LIBRTE_IP_FRAG_MAX_FRAG: u32 = 4;
4948
pub const IP_LAST_FRAG_IDX: _bindgen_ty_1 = _bindgen_ty_1::IP_LAST_FRAG_IDX;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(
4+
dead_code,
5+
non_snake_case,
6+
non_camel_case_types,
7+
non_upper_case_globals
8+
)]
9+
10+
#[repr(C)]
11+
#[derive(Default)]
12+
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
13+
impl<T> __IncompleteArrayField<T> {
14+
#[inline]
15+
pub fn new() -> Self {
16+
__IncompleteArrayField(::std::marker::PhantomData, [])
17+
}
18+
#[inline]
19+
pub unsafe fn as_ptr(&self) -> *const T {
20+
::std::mem::transmute(self)
21+
}
22+
#[inline]
23+
pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
24+
::std::mem::transmute(self)
25+
}
26+
#[inline]
27+
pub unsafe fn as_slice(&self, len: usize) -> &[T] {
28+
::std::slice::from_raw_parts(self.as_ptr(), len)
29+
}
30+
#[inline]
31+
pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] {
32+
::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
33+
}
34+
}
35+
impl<T> ::std::fmt::Debug for __IncompleteArrayField<T> {
36+
fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
37+
fmt.write_str("__IncompleteArrayField")
38+
}
39+
}
40+
impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
41+
#[inline]
42+
fn clone(&self) -> Self {
43+
Self::new()
44+
}
45+
}
46+
#[repr(C)]
47+
#[derive(Debug, Default)]
48+
pub struct dm_deps {
49+
pub count: ::std::os::raw::c_uint,
50+
pub filler: ::std::os::raw::c_uint,
51+
pub device: __IncompleteArrayField<::std::os::raw::c_ulonglong>,
52+
}
53+
#[test]
54+
fn bindgen_test_layout_dm_deps() {
55+
assert_eq!(
56+
::std::mem::size_of::<dm_deps>(),
57+
8usize,
58+
concat!("Size of: ", stringify!(dm_deps))
59+
);
60+
assert_eq!(
61+
::std::mem::align_of::<dm_deps>(),
62+
8usize,
63+
concat!("Alignment of ", stringify!(dm_deps))
64+
);
65+
assert_eq!(
66+
unsafe { &(*(::std::ptr::null::<dm_deps>())).count as *const _ as usize },
67+
0usize,
68+
concat!(
69+
"Offset of field: ",
70+
stringify!(dm_deps),
71+
"::",
72+
stringify!(count)
73+
)
74+
);
75+
assert_eq!(
76+
unsafe { &(*(::std::ptr::null::<dm_deps>())).filler as *const _ as usize },
77+
4usize,
78+
concat!(
79+
"Offset of field: ",
80+
stringify!(dm_deps),
81+
"::",
82+
stringify!(filler)
83+
)
84+
);
85+
assert_eq!(
86+
unsafe { &(*(::std::ptr::null::<dm_deps>())).device as *const _ as usize },
87+
8usize,
88+
concat!(
89+
"Offset of field: ",
90+
stringify!(dm_deps),
91+
"::",
92+
stringify!(device)
93+
)
94+
);
95+
}

tests/expectations/tests/zero-sized-array.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99

1010
#[repr(C)]
1111
#[derive(Default)]
12-
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
12+
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
1313
impl<T> __IncompleteArrayField<T> {
1414
#[inline]
1515
pub fn new() -> Self {
16-
__IncompleteArrayField(::std::marker::PhantomData)
16+
__IncompleteArrayField(::std::marker::PhantomData, [])
1717
}
1818
#[inline]
1919
pub unsafe fn as_ptr(&self) -> *const T {
@@ -43,7 +43,6 @@ impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
4343
Self::new()
4444
}
4545
}
46-
impl<T> ::std::marker::Copy for __IncompleteArrayField<T> {}
4746
/// Bizarrely enough, this should *not* get an `_address` field.
4847
#[repr(C)]
4948
#[derive(Debug, Default)]

tests/headers/zero-size-array-align.h

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
struct dm_deps {
2+
unsigned count;
3+
unsigned filler;
4+
unsigned long long device[0];
5+
};

0 commit comments

Comments
 (0)