Skip to content
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

C union containing only flexible array members does not generate Rust union #3130

Open
tamird opened this issue Feb 15, 2025 · 1 comment
Open
Labels
rust-for-linux Issues relevant to the Rust for Linux project

Comments

@tamird
Copy link
Contributor

tamird commented Feb 15, 2025

Consider this type from Linux:

struct bpf_prog {
	...
	/* Instructions for interpreter */
	union {
		DECLARE_FLEX_ARRAY(struct sock_filter, insns);
		DECLARE_FLEX_ARRAY(struct bpf_insn, insnsi);
	};
};

This generates:

#[repr(C)]
pub struct bpf_prog {
    ...
    pub __bindgen_anon_1: bpf_prog__bindgen_ty_1,
}
#[repr(C)]
pub struct bpf_prog__bindgen_ty_1 {
    pub __bindgen_anon_1: __BindgenUnionField<bpf_prog__bindgen_ty_1__bindgen_ty_1>,
    pub __bindgen_anon_2: __BindgenUnionField<bpf_prog__bindgen_ty_1__bindgen_ty_2>,
    pub bindgen_union_field: [u32; 0usize],
}
...

Note that bpf_prog__bindgen_ty_1 is a struct rather than a union and its fields are bindgen wrappers. This happens even in the presence of --default-non-copy-union-style manually_drop. This arises from

if layout.is_some_and(|l| l.size == 0) {
return (false, false);
}

Removing that check generates what I expect:

#[repr(C)]
pub struct bpf_prog {
    ...
    pub __bindgen_anon_1: bpf_prog__bindgen_ty_1,
}
#[repr(C)]
pub union bpf_prog__bindgen_ty_1 {
    pub __bindgen_anon_1: ::core::mem::ManuallyDrop<bpf_prog__bindgen_ty_1__bindgen_ty_1>,
    pub __bindgen_anon_2: ::core::mem::ManuallyDrop<bpf_prog__bindgen_ty_1__bindgen_ty_2>,
}
...

This condition was introduced in 8ac787a but it's not clear to me why. Perhaps this was meant to deal with the fact that unions without any fields are not accepted by the compiler?

cc @emilio

@ojeda
Copy link
Contributor

ojeda commented Feb 15, 2025

I suggest providing expanded code; otherwise, the maintainers need to figure out what this may be referring to. For instance, from my comment Rust-for-Linux/linux#1137 (comment), reduced from struct bpf_array:

struct bpf_array {
    union {
        struct {
            struct {} __empty_value;
            char value[];
        };
    };
};

Related: Rust-for-Linux/linux#1137
Related: Richardhongyu/rfl_empirical_tools#1
Cc @pvdrz

@ojeda ojeda added the rust-for-linux Issues relevant to the Rust for Linux project label Feb 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rust-for-linux Issues relevant to the Rust for Linux project
Projects
None yet
Development

No branches or pull requests

2 participants