-
Notifications
You must be signed in to change notification settings - Fork 747
treat incomplete array as zero length array #456
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise looks good to me, thanks for the fix!
@@ -2,6 +2,8 @@ class C { | |||
int a; | |||
// More than rust limits (32) | |||
char big_array[33]; | |||
char zero_length_array[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this is legal C/C++? (the zero_length_array
and incomplete_array
fields would have the same address).
Could you remove the zero_length_array
field from the test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(or better, test them in two different structs)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, some times, people use zero length array as a mark (another story should be solved), and use incomplete array as the last field
/* define a set of marker types that can be used to refer to set points in the
* mbuf */
__extension__
typedef void *MARKER[0]; /**< generic marker for a point in a structure */
__extension__
typedef uint8_t MARKER8[0]; /**< generic marker with 1B alignment */
__extension__
typedef uint64_t MARKER64[0]; /**< marker that allows us to overwrite 8 bytes
* with a single assignment */
/**
* The generic rte_mbuf, containing a packet mbuf.
*/
struct rte_mbuf {
MARKER cacheline0;
void *buf_addr; /**< Virtual address of segment buffer. */
phys_addr_t buf_physaddr; /**< Physical address of segment buffer. */
uint16_t buf_len; /**< Length of segment buffer. */
/* next 6 bytes are initialised on RX descriptor rearm */
MARKER8 rearm_data;
uint16_t data_off;
struct cmdline_inst {
/* f(parsed_struct, data) */
void (*f)(void *, struct cmdline *, void *);
void *data;
const char *help_str;
cmdline_parse_token_hdr_t *tokens[];
};
I have submitted another patch base on a helper class like __BindgenUnionField
did
#[repr(C)]
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
impl <T> __IncompleteArrayField<T> {
#[inline]
pub fn new() -> Self {
__IncompleteArrayField(::std::marker::PhantomData)
}
#[inline]
pub unsafe fn as_slice(&self, len: usize) -> &[T] {
::std::slice::from_raw_parts(::std::mem::transmute(self), len)
}
#[inline]
pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] {
::std::slice::from_raw_parts_mut(::std::mem::transmute(self), len)
}
}
impl <T> ::std::fmt::Debug for __IncompleteArrayField<T> {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
fmt.write_str("__IncompleteArrayField")
}
}
#[repr(C)]
pub struct C {
pub a: ::std::os::raw::c_int,
pub big_array: [::std::os::raw::c_char; 33usize],
pub zero_length_array: __IncompleteArrayField<::std::os::raw::c_char>,
pub incomplete_array: __IncompleteArrayField<::std::os::raw::c_char>,
}
#[test]
fn bindgen_test_layout_C() {
assert_eq!(::std::mem::size_of::<C>() , 40usize);
assert_eq!(::std::mem::align_of::<C>() , 4usize);
}
So I'm not super-fond of adding a new type just for this, but that being said I don't have any other complaints about this patch, and if you have a use case for the helper methods that's fine for me. I'm slightly concerned about the array type in the static, I need to write a test case using it to verify it works, and then you have my sign-off on this. |
@bors-servo r+ Actually marking them as zero-size array is the correct thing to do, will land a test for this in a few minutes. |
📌 Commit edf7f35 has been approved by |
⚡ Test exempted - status |
treat incomplete array as zero length array fix issue #455
Thanks for the patch! |
Turns out they were broken before rust-lang#456. Let's test it so it doesn't regress.
Turns out they were broken before rust-lang#456. Let's test it so it doesn't regress.
Turns out they were broken before rust-lang#456. Let's test it so it doesn't regress.
In theory, both zero-length array and flexible array member are invalid in C++. Probably better putting them in a C header rather than hpp. |
fix issue #455