diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-03-10 07:06:36 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-03-13 12:15:47 +0100 |
commit | 96b26b308dbfb5acde0ede785dcbb7d276ef98f2 (patch) | |
tree | adbee3a30bc85908ab21f7903e4750f76bf4fb9a | |
parent | 60c3d336760d3b10c637551a2a8beb0f9a588315 (diff) |
codegen: support repr(align).
Fixes #917
-rw-r--r-- | src/codegen/mod.rs | 16 | ||||
-rw-r--r-- | src/features.rs | 8 | ||||
-rw-r--r-- | tests/expectations/tests/repr-align.rs | 35 | ||||
-rw-r--r-- | tests/headers/repr-align.hpp | 6 |
4 files changed, 65 insertions, 0 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 1801520a..950708a0 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1527,6 +1527,7 @@ impl CodeGenerator for CompInfo { }); } + let mut explicit_align = None; if is_opaque { // Opaque item should not have generated methods, fields. debug_assert!(fields.is_empty()); @@ -1534,6 +1535,8 @@ impl CodeGenerator for CompInfo { match layout { Some(l) => { + explicit_align = Some(l.align); + let ty = helpers::blob(l); fields.push(quote! { pub _bindgen_opaque_blob: #ty , @@ -1555,6 +1558,7 @@ impl CodeGenerator for CompInfo { if layout.align == 1 { packed = true; } else { + explicit_align = Some(layout.align); let ty = helpers::blob(Layout::new(0, layout.align)); fields.push(quote! { pub __bindgen_align: #ty , @@ -1637,6 +1641,18 @@ impl CodeGenerator for CompInfo { attributes.push(attributes::repr("C")); } + if ctx.options().rust_features().repr_align() { + if let Some(explicit) = explicit_align { + // Ensure that the struct has the correct alignment even in + // presence of alignas. + let explicit = helpers::ast_ty::int_expr(explicit as i64); + attributes.push(quote! { + #[repr(align(#explicit))] + }); + } + } + + let mut derives = vec![]; if item.can_derive_debug(ctx) { derives.push("Debug"); diff --git a/src/features.rs b/src/features.rs index d4fbd928..fe4f8453 100644 --- a/src/features.rs +++ b/src/features.rs @@ -92,6 +92,8 @@ macro_rules! rust_target_base { => Stable_1_19 => 1.19; /// Rust stable 1.21 => Stable_1_21 => 1.21; + /// Rust stable 1.24 + => Stable_1_24 => 1.24; /// Nightly rust => Nightly => nightly; ); @@ -144,6 +146,8 @@ rust_feature_def!( => thiscall_abi; /// builtin impls for `Clone` ([PR](https://github.com/rust-lang/rust/pull/43690)) => builtin_clone_impls; + /// repr(align) https://github.com/rust-lang/rust/pull/47006 + => repr_align; ); impl From<RustTarget> for RustFeatures { @@ -158,6 +162,10 @@ impl From<RustTarget> for RustFeatures { features.builtin_clone_impls = true; } + if rust_target >= RustTarget::Stable_1_24 { + features.repr_align = true; + } + if rust_target >= RustTarget::Nightly { features.thiscall_abi = true; } diff --git a/tests/expectations/tests/repr-align.rs b/tests/expectations/tests/repr-align.rs new file mode 100644 index 00000000..be9ce9ad --- /dev/null +++ b/tests/expectations/tests/repr-align.rs @@ -0,0 +1,35 @@ +/* automatically generated by rust-bindgen */ + +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] + +#[repr(C)] +#[repr(align(8))] +#[derive(Debug, Default, Copy, Clone)] +pub struct a { + pub b: ::std::os::raw::c_int, + pub c: ::std::os::raw::c_int, + pub __bindgen_align: [u64; 0usize], +} +#[test] +fn bindgen_test_layout_a() { + assert_eq!( + ::std::mem::size_of::<a>(), + 8usize, + concat!("Size of: ", stringify!(a)) + ); + assert_eq!( + ::std::mem::align_of::<a>(), + 8usize, + concat!("Alignment of ", stringify!(a)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<a>())).b as *const _ as usize }, + 0usize, + concat!("Offset of field: ", stringify!(a), "::", stringify!(b)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<a>())).c as *const _ as usize }, + 4usize, + concat!("Offset of field: ", stringify!(a), "::", stringify!(c)) + ); +} diff --git a/tests/headers/repr-align.hpp b/tests/headers/repr-align.hpp new file mode 100644 index 00000000..f0629496 --- /dev/null +++ b/tests/headers/repr-align.hpp @@ -0,0 +1,6 @@ +// bindgen-flags: --rust-target 1.24 -- -std=c++11 + +struct alignas(8) a { + int b; + int c; +}; |