Skip to content

[libclang5] Wrong code generation surfaced by #2787 #2922

@Kriskras99

Description

@Kriskras99

If bindgen does not support libclang5 anymore (very reasonable stance), then this issue can be immediately closed.

This issue was surfaced by #2787

Input C/C++ Header

typedef struct {
    int a;
    _Atomic(struct c *) b;
} d;

Bindgen Invocation

$ bindgen input.h

Actual Results

llvm7/libclang5 generated bindings:

/* automatically generated by rust-bindgen 0.70.1 */

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct d {
    pub a: ::std::os::raw::c_int,
    pub b: d_c,
    pub __bindgen_padding_0: u64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of d"][::std::mem::size_of::<d>() - 16usize];
    ["Alignment of d"][::std::mem::align_of::<d>() - 8usize];
    ["Offset of field: d::a"][::std::mem::offset_of!(d, a) - 0usize];
    ["Offset of field: d::b"][::std::mem::offset_of!(d, b) - 8usize];
};
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct d_c {
    _unused: [u8; 0],
}

causing

error[E0080]: evaluation of constant value failed
  --> llvm7_libclang5.rs:15:31
   |
15 |     ["Offset of field: d::b"][::std::mem::offset_of!(d, b) - 8usize];
   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to compute `4_usize - 8_usize`, which would overflow

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0080`.

llvm11/libclang11 generated bindings (these do work)

/* automatically generated by rust-bindgen 0.70.1 */

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct d {
    pub a: ::std::os::raw::c_int,
    pub b: *mut c,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of d"][::std::mem::size_of::<d>() - 16usize];
    ["Alignment of d"][::std::mem::align_of::<d>() - 8usize];
    ["Offset of field: d::a"][::std::mem::offset_of!(d, a) - 0usize];
    ["Offset of field: d::b"][::std::mem::offset_of!(d, b) - 8usize];
};
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct c {
    pub _address: u8,
}

Expected Results

The bindings to not break the compiler.
Note that it's not only field offsets that can go wrong, in the original header the size_of is also wrong:

error[E0080]: evaluation of constant value failed
   --> /home/christiaan/scate2-dev/rust/target/release-customer/build/julia-sys-346f0adfcf2f3b4c/out/bindings.rs:477:5
    |
477 |     ["Size of jl_mutex_t"][::std::mem::size_of::<jl_mutex_t>() - 16usize];
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 368

I'd like to repeat, that it's perfectly valid to drop libclang5. Even for CentOS 7 users there is the possibility to install libclang11.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions