rust-lang / rust-lang/rust

Add a run-make test that checks our `core::ffi::c_*` types against Clang

Open
#133,058 6 comments 0 reactions 1 assignee View on GitHub

@ricci009 is already working on this.

Since Nov 18, 2024.

A-FFI A-testsuite E-hard E-needs-design E-needs-test T-libs
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:

  1. Loop through each target string in the output of rustc --print target-list

  2. Map the rust target to a LLVM target if they aren't the same

  3. Loop through a list of each c_* type available in core::ffi

  4. 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
    
  5. 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});
    
  6. 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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.