Skip to content

check layout align before padding bytes #495

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/codegen/struct_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
152 changes: 152 additions & 0 deletions tests/expectations/tests/issue-493.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/* automatically generated by rust-bindgen */


#![allow(non_snake_case)]


#[repr(C)]
pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
impl <T> __BindgenUnionField<T> {
#[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 <T> ::std::default::Default for __BindgenUnionField<T> {
#[inline]
fn default() -> Self { Self::new() }
}
impl <T> ::std::clone::Clone for __BindgenUnionField<T> {
#[inline]
fn clone(&self) -> Self { Self::new() }
}
impl <T> ::std::marker::Copy for __BindgenUnionField<T> { }
impl <T> ::std::fmt::Debug for __BindgenUnionField<T> {
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<basic_string_value_type>,
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<basic_string___long<_CharT, _Traits,
_Allocator>>,
pub __lxx: __BindgenUnionField<basic_string___short<_CharT, _Traits,
_Allocator>>,
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<basic_string___long<_CharT, _Traits,
_Allocator>>,
pub __s: __BindgenUnionField<basic_string___short<_CharT, _Traits,
_Allocator>>,
pub __r: __BindgenUnionField<basic_string___raw<_CharT, _Traits,
_Allocator>>,
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() } }
}
47 changes: 47 additions & 0 deletions tests/headers/issue-493.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
template<class _CharT, class _Traits, class _Allocator>
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)};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow, this is why we can't have nice things :(

Thanks for finding this out!


struct __raw
{
size_type __words[__n_words];
};

struct __rep
{
union
{
__long __l;
__short __s;
__raw __r;
};
};
};