Skip to content

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

Merged
merged 4 commits into from
Jan 29, 2017

Conversation

flier
Copy link
Contributor

@flier flier commented Jan 28, 2017

fix issue #455

Copy link
Contributor

@emilio emilio left a 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];
Copy link
Contributor

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?

Copy link
Contributor

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)

Copy link
Contributor Author

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);
}

@emilio
Copy link
Contributor

emilio commented Jan 29, 2017

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.

@emilio
Copy link
Contributor

emilio commented Jan 29, 2017

@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.

@bors-servo
Copy link

📌 Commit edf7f35 has been approved by emilio

@bors-servo
Copy link

⚡ Test exempted - status

@bors-servo bors-servo merged commit edf7f35 into rust-lang:master Jan 29, 2017
bors-servo pushed a commit that referenced this pull request Jan 29, 2017
treat incomplete array as zero length array

fix issue #455
@emilio
Copy link
Contributor

emilio commented Jan 29, 2017

Thanks for the patch!

emilio added a commit to emilio/rust-bindgen that referenced this pull request Jan 29, 2017
Turns out they were broken before
rust-lang#456.

Let's test it so it doesn't regress.
emilio added a commit to emilio/rust-bindgen that referenced this pull request Jan 29, 2017
Turns out they were broken before
rust-lang#456.

Let's test it so it doesn't regress.
emilio added a commit to emilio/rust-bindgen that referenced this pull request Jan 29, 2017
Turns out they were broken before
rust-lang#456.

Let's test it so it doesn't regress.
bors-servo pushed a commit that referenced this pull request Jan 29, 2017
tests: Add an integration test for static arrays.

Turns out they were broken before
#456.

Let's test it so it doesn't regress.

r? @fitzgen
@emilio emilio mentioned this pull request Feb 3, 2017
@upsuper
Copy link
Contributor

upsuper commented Feb 3, 2017

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants