From e08072a1c9343c9c513e059a8a31ee2d1af129a9 Mon Sep 17 00:00:00 2001 From: Flier Lu Date: Wed, 8 Feb 2017 22:08:38 +0800 Subject: [PATCH] check layout align before padding bytes --- src/codegen/struct_layout.rs | 5 +- tests/expectations/tests/issue-493.rs | 152 ++++++++++++++++++++++++++ tests/headers/issue-493.hpp | 47 ++++++++ 3 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 tests/expectations/tests/issue-493.rs create mode 100644 tests/headers/issue-493.hpp diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index 9864057026..f8a88bc24b 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -89,9 +89,12 @@ impl<'a, 'ctx> StructLayoutTracker<'a, 'ctx> { Some(offset) if offset / 8 > self.latest_offset => { (offset / 8 - self.latest_offset, true) } - _ => { + _ if field_layout.align != 0 => { (self.padding_bytes(field_layout), (self.latest_offset % field_layout.align) != 0) } + _ => { + (0, false) + } }; self.latest_offset += padding_bytes; diff --git a/tests/expectations/tests/issue-493.rs b/tests/expectations/tests/issue-493.rs new file mode 100644 index 0000000000..f8814bd396 --- /dev/null +++ b/tests/expectations/tests/issue-493.rs @@ -0,0 +1,152 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +pub struct __BindgenUnionField(::std::marker::PhantomData); +impl __BindgenUnionField { + #[inline] + pub fn new() -> Self { __BindgenUnionField(::std::marker::PhantomData) } + #[inline] + pub unsafe fn as_ref(&self) -> &T { ::std::mem::transmute(self) } + #[inline] + pub unsafe fn as_mut(&mut self) -> &mut T { ::std::mem::transmute(self) } +} +impl ::std::default::Default for __BindgenUnionField { + #[inline] + fn default() -> Self { Self::new() } +} +impl ::std::clone::Clone for __BindgenUnionField { + #[inline] + fn clone(&self) -> Self { Self::new() } +} +impl ::std::marker::Copy for __BindgenUnionField { } +impl ::std::fmt::Debug for __BindgenUnionField { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fmt.write_str("__BindgenUnionField") + } +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct basic_string<_CharT, _Traits, _Allocator> { + pub _address: u8, + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +pub type basic_string_size_type = ::std::os::raw::c_ulonglong; +pub type basic_string_value_type = ::std::os::raw::c_char; +pub type basic_string_pointer = *mut basic_string_value_type; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct basic_string___long<_CharT, _Traits, _Allocator> { + pub __cap_: basic_string_size_type, + pub __size_: basic_string_size_type, + pub __data_: basic_string_pointer, + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string___long<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +pub const basic_string___min_cap: basic_string__bindgen_ty_1 = + basic_string__bindgen_ty_1::__min_cap; +#[repr(i32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum basic_string__bindgen_ty_1 { __min_cap = 0, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct basic_string___short<_CharT, _Traits, _Allocator> { + pub __bindgen_anon_1: basic_string___short__bindgen_ty_1<_CharT, _Traits, + _Allocator>, + pub __data_: *mut basic_string_value_type, + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +#[repr(C)] +#[derive(Debug, Default, Copy, Clone)] +pub struct basic_string___short__bindgen_ty_1<_CharT, _Traits, _Allocator> { + pub __size_: __BindgenUnionField<::std::os::raw::c_uchar>, + pub __lx: __BindgenUnionField, + pub bindgen_union_field: u8, + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string___short<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct basic_string___ulx<_CharT, _Traits, _Allocator> { + pub __lx: __BindgenUnionField>, + pub __lxx: __BindgenUnionField>, + pub bindgen_union_field: [u8; 0usize], + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string___ulx<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +pub const basic_string___n_words: basic_string__bindgen_ty_2 = + basic_string__bindgen_ty_2::__n_words; +#[repr(i32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum basic_string__bindgen_ty_2 { __n_words = 0, } +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct basic_string___raw<_CharT, _Traits, _Allocator> { + pub __words: *mut basic_string_size_type, + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string___raw<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct basic_string___rep<_CharT, _Traits, _Allocator> { + pub __bindgen_anon_1: basic_string___rep__bindgen_ty_1<_CharT, _Traits, + _Allocator>, + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct basic_string___rep__bindgen_ty_1<_CharT, _Traits, _Allocator> { + pub __l: __BindgenUnionField>, + pub __s: __BindgenUnionField>, + pub __r: __BindgenUnionField>, + pub bindgen_union_field: [u8; 0usize], + pub _phantom_0: ::std::marker::PhantomData<_CharT>, + pub _phantom_1: ::std::marker::PhantomData<_Traits>, + pub _phantom_2: ::std::marker::PhantomData<_Allocator>, +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string___rep__bindgen_ty_1<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string___rep<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} +impl <_CharT, _Traits, _Allocator> Default for + basic_string<_CharT, _Traits, _Allocator> { + fn default() -> Self { unsafe { ::std::mem::zeroed() } } +} diff --git a/tests/headers/issue-493.hpp b/tests/headers/issue-493.hpp new file mode 100644 index 0000000000..975ef5ceea --- /dev/null +++ b/tests/headers/issue-493.hpp @@ -0,0 +1,47 @@ +template +class basic_string +{ +public: + typedef unsigned long long size_type; + typedef char value_type; + typedef value_type * pointer; + + struct __long + { + size_type __cap_; + size_type __size_; + pointer __data_; + }; + + enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ? + (sizeof(__long) - 1)/sizeof(value_type) : 2}; + + struct __short + { + union + { + unsigned char __size_; + value_type __lx; + }; + value_type __data_[__min_cap]; + }; + + union __ulx{__long __lx; __short __lxx;}; + + enum {__n_words = sizeof(__ulx) / sizeof(size_type)}; + + struct __raw + { + size_type __words[__n_words]; + }; + + struct __rep + { + union + { + __long __l; + __short __s; + __raw __r; + }; + }; +}; \ No newline at end of file