Add a run-make test that checks our `core::ffi::c_*` types against Clang
@ricci009 is already working on this.
Since Nov 18, 2024.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
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 https://github.com/rust-lang/rust/issues/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_TARGETto 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-codegenand 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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.