Skip to content

Commit fa12451

Browse files
committed
codegen: Don't skip alignment checks if we support repr align.
Plus fix the check that avoids us generating explicit alignment fields for structs aligned to more than pointer-size. Fixes #1291
1 parent 473cfc2 commit fa12451

File tree

4 files changed

+215
-4
lines changed

4 files changed

+215
-4
lines changed

src/codegen/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1776,8 +1776,9 @@ impl CodeGenerator for CompInfo {
17761776
let align = layout.align;
17771777

17781778
let check_struct_align =
1779-
if align > ctx.target_pointer_size() {
1780-
// FIXME when [RFC 1358](https://github.com/rust-lang/rust/issues/33626) ready
1779+
if align > ctx.target_pointer_size() &&
1780+
!ctx.options().rust_features().repr_align
1781+
{
17811782
None
17821783
} else {
17831784
Some(quote! {

src/codegen/struct_layout.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,18 @@ impl<'a> StructLayoutTracker<'a> {
286286
}
287287

288288
pub fn requires_explicit_align(&self, layout: Layout) -> bool {
289-
self.max_field_align < layout.align &&
290-
layout.align <= self.ctx.target_pointer_size()
289+
if self.max_field_align >= layout.align {
290+
return false;
291+
}
292+
// At this point we require explicit alignment, but we may not be able
293+
// to generate the right bits, let's double check.
294+
if self.ctx.options().rust_features().repr_align {
295+
return true;
296+
}
297+
298+
// We can only generate up-to a word of alignment unless we support
299+
// repr(align).
300+
layout.align <= self.ctx.target_pointer_size()
291301
}
292302

293303
fn padding_bytes(&self, layout: Layout) -> usize {
+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
4+
5+
#[repr(C)]
6+
#[repr(align(16))]
7+
#[derive(Debug, Default, Copy, Clone)]
8+
pub struct RTCRay {
9+
pub org: [f32; 3usize],
10+
pub align0: f32,
11+
pub dir: [f32; 3usize],
12+
pub align1: f32,
13+
pub tnear: f32,
14+
pub tfar: f32,
15+
pub time: f32,
16+
pub mask: ::std::os::raw::c_uint,
17+
pub Ng: [f32; 3usize],
18+
pub align2: f32,
19+
pub u: f32,
20+
pub v: f32,
21+
pub geomID: ::std::os::raw::c_uint,
22+
pub primID: ::std::os::raw::c_uint,
23+
pub instID: ::std::os::raw::c_uint,
24+
pub __bindgen_padding_0: [u32; 3usize],
25+
pub __bindgen_align: [u8; 0usize],
26+
}
27+
#[test]
28+
fn bindgen_test_layout_RTCRay() {
29+
assert_eq!(
30+
::std::mem::size_of::<RTCRay>(),
31+
96usize,
32+
concat!("Size of: ", stringify!(RTCRay))
33+
);
34+
assert_eq!(
35+
::std::mem::align_of::<RTCRay>(),
36+
16usize,
37+
concat!("Alignment of ", stringify!(RTCRay))
38+
);
39+
assert_eq!(
40+
unsafe { &(*(::std::ptr::null::<RTCRay>())).org as *const _ as usize },
41+
0usize,
42+
concat!(
43+
"Offset of field: ",
44+
stringify!(RTCRay),
45+
"::",
46+
stringify!(org)
47+
)
48+
);
49+
assert_eq!(
50+
unsafe { &(*(::std::ptr::null::<RTCRay>())).align0 as *const _ as usize },
51+
12usize,
52+
concat!(
53+
"Offset of field: ",
54+
stringify!(RTCRay),
55+
"::",
56+
stringify!(align0)
57+
)
58+
);
59+
assert_eq!(
60+
unsafe { &(*(::std::ptr::null::<RTCRay>())).dir as *const _ as usize },
61+
16usize,
62+
concat!(
63+
"Offset of field: ",
64+
stringify!(RTCRay),
65+
"::",
66+
stringify!(dir)
67+
)
68+
);
69+
assert_eq!(
70+
unsafe { &(*(::std::ptr::null::<RTCRay>())).align1 as *const _ as usize },
71+
28usize,
72+
concat!(
73+
"Offset of field: ",
74+
stringify!(RTCRay),
75+
"::",
76+
stringify!(align1)
77+
)
78+
);
79+
assert_eq!(
80+
unsafe { &(*(::std::ptr::null::<RTCRay>())).tnear as *const _ as usize },
81+
32usize,
82+
concat!(
83+
"Offset of field: ",
84+
stringify!(RTCRay),
85+
"::",
86+
stringify!(tnear)
87+
)
88+
);
89+
assert_eq!(
90+
unsafe { &(*(::std::ptr::null::<RTCRay>())).tfar as *const _ as usize },
91+
36usize,
92+
concat!(
93+
"Offset of field: ",
94+
stringify!(RTCRay),
95+
"::",
96+
stringify!(tfar)
97+
)
98+
);
99+
assert_eq!(
100+
unsafe { &(*(::std::ptr::null::<RTCRay>())).time as *const _ as usize },
101+
40usize,
102+
concat!(
103+
"Offset of field: ",
104+
stringify!(RTCRay),
105+
"::",
106+
stringify!(time)
107+
)
108+
);
109+
assert_eq!(
110+
unsafe { &(*(::std::ptr::null::<RTCRay>())).mask as *const _ as usize },
111+
44usize,
112+
concat!(
113+
"Offset of field: ",
114+
stringify!(RTCRay),
115+
"::",
116+
stringify!(mask)
117+
)
118+
);
119+
assert_eq!(
120+
unsafe { &(*(::std::ptr::null::<RTCRay>())).Ng as *const _ as usize },
121+
48usize,
122+
concat!(
123+
"Offset of field: ",
124+
stringify!(RTCRay),
125+
"::",
126+
stringify!(Ng)
127+
)
128+
);
129+
assert_eq!(
130+
unsafe { &(*(::std::ptr::null::<RTCRay>())).align2 as *const _ as usize },
131+
60usize,
132+
concat!(
133+
"Offset of field: ",
134+
stringify!(RTCRay),
135+
"::",
136+
stringify!(align2)
137+
)
138+
);
139+
assert_eq!(
140+
unsafe { &(*(::std::ptr::null::<RTCRay>())).u as *const _ as usize },
141+
64usize,
142+
concat!("Offset of field: ", stringify!(RTCRay), "::", stringify!(u))
143+
);
144+
assert_eq!(
145+
unsafe { &(*(::std::ptr::null::<RTCRay>())).v as *const _ as usize },
146+
68usize,
147+
concat!("Offset of field: ", stringify!(RTCRay), "::", stringify!(v))
148+
);
149+
assert_eq!(
150+
unsafe { &(*(::std::ptr::null::<RTCRay>())).geomID as *const _ as usize },
151+
72usize,
152+
concat!(
153+
"Offset of field: ",
154+
stringify!(RTCRay),
155+
"::",
156+
stringify!(geomID)
157+
)
158+
);
159+
assert_eq!(
160+
unsafe { &(*(::std::ptr::null::<RTCRay>())).primID as *const _ as usize },
161+
76usize,
162+
concat!(
163+
"Offset of field: ",
164+
stringify!(RTCRay),
165+
"::",
166+
stringify!(primID)
167+
)
168+
);
169+
assert_eq!(
170+
unsafe { &(*(::std::ptr::null::<RTCRay>())).instID as *const _ as usize },
171+
80usize,
172+
concat!(
173+
"Offset of field: ",
174+
stringify!(RTCRay),
175+
"::",
176+
stringify!(instID)
177+
)
178+
);
179+
}

tests/headers/issue-1291.hpp

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// bindgen-flags: --rust-target 1.25
2+
// bindgen-unstable
3+
4+
struct __attribute__((aligned(16))) RTCRay
5+
{
6+
float org[3];
7+
float align0;
8+
float dir[3];
9+
float align1;
10+
float tnear;
11+
float tfar;
12+
float time;
13+
unsigned mask;
14+
float Ng[3];
15+
float align2;
16+
float u;
17+
float v;
18+
unsigned geomID;
19+
unsigned primID;
20+
unsigned instID;
21+
};

0 commit comments

Comments
 (0)