Skip to content

Commit d6b69bf

Browse files
committed
codegen: support repr(align).
Fixes rust-lang#917
1 parent f36f4e3 commit d6b69bf

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

src/codegen/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1527,13 +1527,16 @@ impl CodeGenerator for CompInfo {
15271527
});
15281528
}
15291529

1530+
let mut explicit_align = None;
15301531
if is_opaque {
15311532
// Opaque item should not have generated methods, fields.
15321533
debug_assert!(fields.is_empty());
15331534
debug_assert!(methods.is_empty());
15341535

15351536
match layout {
15361537
Some(l) => {
1538+
explicit_align = Some(l.align);
1539+
15371540
let ty = helpers::blob(l);
15381541
fields.push(quote! {
15391542
pub _bindgen_opaque_blob: #ty ,
@@ -1555,6 +1558,7 @@ impl CodeGenerator for CompInfo {
15551558
if layout.align == 1 {
15561559
packed = true;
15571560
} else {
1561+
explicit_align = Some(layout.align);
15581562
let ty = helpers::blob(Layout::new(0, layout.align));
15591563
fields.push(quote! {
15601564
pub __bindgen_align: #ty ,
@@ -1637,6 +1641,18 @@ impl CodeGenerator for CompInfo {
16371641
attributes.push(attributes::repr("C"));
16381642
}
16391643

1644+
if ctx.options().rust_features().repr_align() {
1645+
if let Some(explicit) = explicit_align {
1646+
// Ensure that the struct has the correct alignment even in
1647+
// presence of alignas.
1648+
let explicit = helpers::ast_ty::int_expr(explicit as i64);
1649+
attributes.push(quote! {
1650+
#[repr(align(#explicit))]
1651+
});
1652+
}
1653+
}
1654+
1655+
16401656
let mut derives = vec![];
16411657
if item.can_derive_debug(ctx) {
16421658
derives.push("Debug");

src/features.rs

+8
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ macro_rules! rust_target_base {
9292
=> Stable_1_19 => 1.19;
9393
/// Rust stable 1.21
9494
=> Stable_1_21 => 1.21;
95+
/// Rust stable 1.24
96+
=> Stable_1_24 => 1.24;
9597
/// Nightly rust
9698
=> Nightly => nightly;
9799
);
@@ -144,6 +146,8 @@ rust_feature_def!(
144146
=> thiscall_abi;
145147
/// builtin impls for `Clone` ([PR](https://github.com/rust-lang/rust/pull/43690))
146148
=> builtin_clone_impls;
149+
/// repr(align) https://github.com/rust-lang/rust/pull/47006
150+
=> repr_align;
147151
);
148152

149153
impl From<RustTarget> for RustFeatures {
@@ -158,6 +162,10 @@ impl From<RustTarget> for RustFeatures {
158162
features.builtin_clone_impls = true;
159163
}
160164

165+
if rust_target >= RustTarget::Stable_1_24 {
166+
features.repr_align = true;
167+
}
168+
161169
if rust_target >= RustTarget::Nightly {
162170
features.thiscall_abi = true;
163171
}
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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(8))]
7+
#[derive(Debug, Default, Copy, Clone)]
8+
pub struct a {
9+
pub b: ::std::os::raw::c_int,
10+
pub c: ::std::os::raw::c_int,
11+
pub __bindgen_align: [u64; 0usize],
12+
}
13+
#[test]
14+
fn bindgen_test_layout_a() {
15+
assert_eq!(
16+
::std::mem::size_of::<a>(),
17+
8usize,
18+
concat!("Size of: ", stringify!(a))
19+
);
20+
assert_eq!(
21+
::std::mem::align_of::<a>(),
22+
8usize,
23+
concat!("Alignment of ", stringify!(a))
24+
);
25+
assert_eq!(
26+
unsafe { &(*(::std::ptr::null::<a>())).b as *const _ as usize },
27+
0usize,
28+
concat!("Offset of field: ", stringify!(a), "::", stringify!(b))
29+
);
30+
assert_eq!(
31+
unsafe { &(*(::std::ptr::null::<a>())).c as *const _ as usize },
32+
4usize,
33+
concat!("Offset of field: ", stringify!(a), "::", stringify!(c))
34+
);
35+
}

tests/headers/repr-align.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// bindgen-flags: --rust-target 1.24 -- -std=c++11
2+
3+
struct alignas(8) a {
4+
int b;
5+
int c;
6+
};

0 commit comments

Comments
 (0)