forked from rust-lang/rust-bindgen
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Be conservative about deriving Debug/Default with large alignment
When there is large enough alignment that we might generate padding which has more members that `RUST_DERIVE_IN_ARRAY_LIMIT`, we can break our ability to derive traits. This commit solves this issue conservatively: there are cases where we leave a derive on the table, because in order to know that we could add that derive, we would need to compute padding before we determine whether we can derive. Fixes rust-lang#648
- Loading branch information
Showing
9 changed files
with
113 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
tests/expectations/tests/issue-648-derive-debug-with-padding.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* automatically generated by rust-bindgen */ | ||
|
||
|
||
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] | ||
|
||
|
||
/// We emit a `[u8; 63usize]` padding field for this struct, which cannot derive | ||
/// Debug because 63 is over the hard coded limit. (Yes, this struct doesn't end | ||
/// up with the reight alignment, we're waiting on `#[repr(align="N")]` to land | ||
/// in rustc). | ||
#[repr(C)] | ||
#[derive(Copy)] | ||
pub struct NoDebug { | ||
pub c: ::std::os::raw::c_char, | ||
pub __bindgen_padding_0: [u8; 63usize], | ||
} | ||
#[test] | ||
fn bindgen_test_layout_NoDebug() { | ||
assert_eq!(::std::mem::size_of::<NoDebug>() , 64usize , concat ! ( | ||
"Size of: " , stringify ! ( NoDebug ) )); | ||
assert_eq! (unsafe { | ||
& ( * ( 0 as * const NoDebug ) ) . c as * const _ as usize } , | ||
0usize , concat ! ( | ||
"Alignment of field: " , stringify ! ( NoDebug ) , "::" , | ||
stringify ! ( c ) )); | ||
} | ||
impl Clone for NoDebug { | ||
fn clone(&self) -> Self { *self } | ||
} | ||
impl Default for NoDebug { | ||
fn default() -> Self { unsafe { ::std::mem::zeroed() } } | ||
} | ||
/// This should derive Debug because the padding size is less than the max derive | ||
/// Debug impl for arrays. However, we conservatively don't derive Debug because | ||
/// we determine Debug derive-ability before we compute padding, which happens at | ||
/// codegen. (Again, we expect to get the alignment wrong for similar reasons.) | ||
#[repr(C)] | ||
#[derive(Copy)] | ||
pub struct ShouldDeriveDebugButDoesNot { | ||
pub c: [::std::os::raw::c_char; 32usize], | ||
pub d: ::std::os::raw::c_char, | ||
pub __bindgen_padding_0: [u8; 31usize], | ||
} | ||
#[test] | ||
fn bindgen_test_layout_ShouldDeriveDebugButDoesNot() { | ||
assert_eq!(::std::mem::size_of::<ShouldDeriveDebugButDoesNot>() , 64usize | ||
, concat ! ( | ||
"Size of: " , stringify ! ( ShouldDeriveDebugButDoesNot ) )); | ||
assert_eq! (unsafe { | ||
& ( * ( 0 as * const ShouldDeriveDebugButDoesNot ) ) . c as * | ||
const _ as usize } , 0usize , concat ! ( | ||
"Alignment of field: " , stringify ! ( | ||
ShouldDeriveDebugButDoesNot ) , "::" , stringify ! ( c ) )); | ||
assert_eq! (unsafe { | ||
& ( * ( 0 as * const ShouldDeriveDebugButDoesNot ) ) . d as * | ||
const _ as usize } , 32usize , concat ! ( | ||
"Alignment of field: " , stringify ! ( | ||
ShouldDeriveDebugButDoesNot ) , "::" , stringify ! ( d ) )); | ||
} | ||
impl Clone for ShouldDeriveDebugButDoesNot { | ||
fn clone(&self) -> Self { *self } | ||
} | ||
impl Default for ShouldDeriveDebugButDoesNot { | ||
fn default() -> Self { unsafe { ::std::mem::zeroed() } } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* We emit a `[u8; 63usize]` padding field for this struct, which cannot derive | ||
* Debug because 63 is over the hard coded limit. (Yes, this struct doesn't end | ||
* up with the reight alignment, we're waiting on `#[repr(align="N")]` to land | ||
* in rustc). | ||
*/ | ||
struct NoDebug { | ||
char c; | ||
// padding of 63 bytes | ||
} __attribute__((__aligned__(64))); | ||
|
||
/** | ||
* This should derive Debug because the padding size is less than the max derive | ||
* Debug impl for arrays. However, we conservatively don't derive Debug because | ||
* we determine Debug derive-ability before we compute padding, which happens at | ||
* codegen. (Again, we expect to get the alignment wrong for similar reasons.) | ||
*/ | ||
struct ShouldDeriveDebugButDoesNot { | ||
char c[32]; | ||
char d; | ||
// padding of 31 bytes | ||
} __attribute__((__aligned__(64))); |