Description
It would be good to have a test that our C interop types are always compatible with C (c_char
, c_long
, c_longlong
all vary to some extent). This will more or less be what @taiki-e did at #129945, just rolled into a run-make test rather than a shell script.
The test will basically need to do the following:
-
Loop through each target string in the output of
rustc --print target-list
-
Map the rust target to a LLVM target if they aren't the same
-
Loop through a list of each
c_*
type available incore::ffi
-
Query
clang -E -dM -x c /dev/null -target LLVM_TARGET
to get a list of builtin definitions. Of note will be something like the following (comments added by me)#define __CHAR_BIT__ 8 // c_char #define __CHAR_UNSIGNED__ 1 // char signedness #define __SIZEOF_DOUBLE__ 8 // c_double #define __SIZEOF_FLOAT__ 4 // c_float #define __SIZEOF_INT__ 4 // c_int #define __SIZEOF_LONG_DOUBLE__ 16 // c_longdouble #define __SIZEOF_LONG_LONG__ 8 // c_longlong #define __SIZEOF_LONG__ 4 // c_long #define __SIZEOF_POINTER__ 4 // *const c_void #define __SIZEOF_PTRDIFF_T__ 4 // c_ptrdiff_t #define __SIZEOF_SHORT__ 2 // c_short #define __SIZEOF_SIZE_T__ 4 // c_size_t #define __BOOL_WIDTH__ 8 // bool #define __INTPTR_WIDTH__ 32 // isize #define __INT_WIDTH__ 32 // c_int #define __LLONG_WIDTH__ 64 // c_longlong #define __LONG_WIDTH__ 32 // c_long #define __POINTER_WIDTH__ 32 // *const c_void #define __PTRDIFF_WIDTH__ 32 // c_ptrdiff_t #define __SHRT_WIDTH__ 16 // c_short #define __SIZE_WIDTH__ 32 // c_size_t #define __UINTPTR_WIDTH__ 32 // usize
-
Use the above to construct a simple Rust program that can verify the sizes and (when applicable) signedness line up at compile time. Probably do an assignment that will catch mismatched types plus a const assert for anything that doesn't have literals.
// input to check `c_short` const C_SHORT: u{c_sizeof_short} = 0; const RUST_SHORT: core::ffi::c_short = C_SHORT; ```rust // input to check pointer width const _: () = assert!(size_of::<*const core::ffi::c_void>() * 8 == {c_pointer_width});
-
Run
rustc -Z no-codegen
and check success/failure against a list of xfail targets.
run_make_support
has clang
available, example usage: https://github.com/rust-lang/rust/blob/e84902d35a4d3039c794e139eb12fba3624c5ff1/tests/run-make/cross-lang-lto-clang/rmake.rs. There is probably some way we could check this on MSVC targets too.