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

layout tests fail for max_align_t on debian sid.i386 #2991

Open
plugwash opened this issue Nov 26, 2024 · 1 comment
Open

layout tests fail for max_align_t on debian sid.i386 #2991

plugwash opened this issue Nov 26, 2024 · 1 comment

Comments

@plugwash
Copy link

While working on updating the rust-bindgen package in debian sid, I ran into a bindgen layout error with leptonica-sys. After some experimentation this failure seems to be caused by building bindings for stddef.h.

As a reduced testcase the following commands

echo '#include <stddef.h>' > wrapper.h
bindgen wrapper.h

resulted in

/* automatically generated by rust-bindgen 0.70.1 */

pub type wchar_t = ::std::os::raw::c_int;
#[repr(C)]
#[repr(align(8))]
#[derive(Debug, Copy, Clone)]
pub struct max_align_t {
    pub __clang_max_align_nonce1: ::std::os::raw::c_longlong,
    pub __clang_max_align_nonce2: f64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of max_align_t"][::std::mem::size_of::<max_align_t>() - 24usize];
    ["Alignment of max_align_t"][::std::mem::align_of::<max_align_t>() - 8usize];
    ["Offset of field: max_align_t::__clang_max_align_nonce1"]
        [::std::mem::offset_of!(max_align_t, __clang_max_align_nonce1) - 0usize];
    ["Offset of field: max_align_t::__clang_max_align_nonce2"]
        [::std::mem::offset_of!(max_align_t, __clang_max_align_nonce2) - 8usize];
};

I wrote a small c test program to see what size the c compilers thought max_align_t should have, worryingly gcc and clang gave different results with gcc giving a result of 48 and clang a result of only 24.

max_align_t does not seem to be defined in any system headers, so I presume there is some built-in magic going on in gcc and clang.

@pvdrz
Copy link
Contributor

pvdrz commented Nov 26, 2024

max_align_t comes from /usr/lib/clang/18/include/__stddef_max_align_t.h on my system:

/*===---- __stddef_max_align_t.h - Definition of max_align_t ---------------===
 *
 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 * See https://llvm.org/LICENSE.txt for license information.
 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 *
 *===-----------------------------------------------------------------------===
 */

#ifndef __CLANG_MAX_ALIGN_T_DEFINED
#define __CLANG_MAX_ALIGN_T_DEFINED

#if defined(_MSC_VER)
typedef double max_align_t;
#elif defined(__APPLE__)
typedef long double max_align_t;
#else
// Define 'max_align_t' to match the GCC definition.
typedef struct {
  long long __clang_max_align_nonce1
      __attribute__((__aligned__(__alignof__(long long))));
  long double __clang_max_align_nonce2
      __attribute__((__aligned__(__alignof__(long double))));
} max_align_t;
#endif

#endif

so it seems clang is trying to match gcc's definition of it. In either case, I think part of the issue here is that long double is not being translated properly by bindgen or something. So definitely a bug in our side.

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

No branches or pull requests

2 participants