gnzlbg / ctest

Automatic testing of FFI bindings for Rust
https://docs.rs/ctest
Apache License 2.0
122 stars 29 forks source link

References in C FFI should emit the restrict qualifier in the tests #68

Open gnzlbg opened 5 years ago

gnzlbg commented 5 years ago

When a C API has a restrict pointer, int foo(int * restrict); the pointer must not alias any other pointer. In the Rust side, this means that a raw *mut c_int pointer is not enough, and a &mut c_int must be used. Otherwise, the API is "unsound", as in, it allows passing it aliasing pointers.

However, some of these APIs do not require the pointer to point to initialize memory, that is, passing them a pointer to an uninitialized value is "ok" for C. Doing that via &mut c_int might be UB, and we might need to generate "something else" here.

This came up when validating the FFI wrapper in libc of lio_listio in FreeBSD, which takes a *const noalias *mut noalias T. Right now, we use *mut T and call it a day, but when validating the bindings, clang rightfully complains that our type is not compatible with the C type because it is missing the restrict qualifier. That is, we would be calling a function type that requires noalias from a prototype that does not, which is unsound.

AFAICT there is no way to express this from Rust. The first step here would be to start using &/&mut since that would make the API sound, even though that would forbid passing pointers to uninitialized memory.

cc @ralfj @centril

gnzlbg commented 5 years ago

cc @joshtriplett

gnzlbg commented 5 years ago

Update: the lio_listio function in musl has the same issue.