rust-bindgen icon indicating copy to clipboard operation
rust-bindgen copied to clipboard

Bindgen >=0.58 produces an invalid union with both packed and align representation hints

Open yutannihilation opened this issue 3 years ago • 4 comments

I tried to bump the version, but found this error on Windows with cross-compilation.

Input C/C++ Header

#include <math.h>

or

#define _CRT_PACKING 8
#pragma pack(push,_CRT_PACKING)

typedef union __mingw_ldbl_type_t
{
  long double x;
  struct {
    unsigned int low, high;
    int sign_exponent : 16;
    int res1 : 16;
    int res0 : 32;
  } lh;
} __mingw_ldbl_type_t;

Bindgen Invocation

cargo +stable-msvc build --target x86_64-pc-windows-gnu
bindgen::Builder::default()
    .header("input.h")
    .generate()
    .unwrap()

Actual Results

error[E0587]: type has conflicting packed and align representation hints
   --> C:\Users\Yutani\Documents\GitHub\libR-sys\target\x86_64-pc-windows-gnu\debug\build\libR-sys-4d11865a7eb8fac8\out/bindings.rs:747:1
    |
747 | / pub union __mingw_ldbl_type_t {
748 | |     pub x: u128,
749 | |     pub lh: __mingw_ldbl_type_t__bindgen_ty_1,
750 | | }
    | |_^

For more information about this error, try `rustc --explain E0587`.
error: could not compile `libR-sys` due to previous error

The diff between bindgen 0.57 and 0.58:

  #[repr(C, packed(8))]
+ #[repr(align(8))]
  #[derive(Copy, Clone)]
  pub union __mingw_ldbl_type_t {
      pub x: u128,
      pub lh: __mingw_ldbl_type_t__bindgen_ty_1,
-     _bindgen_union_align: [u64; 2usize],
  }

Expected Results

yutannihilation avatar Feb 10 '22 15:02 yutannihilation

I suspect the change introduced by https://github.com/rust-lang/rust-bindgen/pull/1984 relates here as it removed _bindgen_union_align, but I'm not sure about the details.

yutannihilation avatar Feb 10 '22 15:02 yutannihilation

I'm running into this error on bindgen 0.64.0. How do I work around this issue?

eliaxelang007 avatar Apr 01 '23 10:04 eliaxelang007

I don't remember well, but, in my case, the workaround was to remove <math.h> or to add __mingw_ldbl_type_t to the blocklist.

yutannihilation avatar Apr 01 '23 10:04 yutannihilation

I am stuck on this issue as well with bindgen version 0.66.1. I have a union that contains the __int128 type. The following code:

#pragma pack(push, 1)

typedef union
{
    unsigned __int128 m;
} u;

#pragma pack(pop)

produces the following error:

error[E0587]: type has conflicting packed and align representation hints

Without the pack pragma only #[repr(align(16))] is present. With the pack pragma both #[repr(pack)] and #[repr(align(1))] (notice that this is now 1) are there which causes the error. Since with packing the align directive changes to 1 as well I don't see the need to output it and this just seems like a bug unless I'm missing something.

Edit, for completeness sake:

with pack:

#[repr(C, packed)]
#[repr(align(1))]
#[derive(Copy, Clone)]
pub union u {
    pub m: u128,
}

without pack:

#[repr(C)]
#[repr(align(16))]
#[derive(Copy, Clone)]
pub union u {
    pub m: u128,
}

aleksa2808 avatar Aug 09 '23 16:08 aleksa2808