Add a special case for CStr/CString in the improper_ctypes lint

Instead of saying to "consider adding a `#[repr(C)]` or
`#[repr(transparent)]` attribute to this struct", we now tell users to
"Use `*const ffi::c_char` instead, and pass the value from
`CStr::as_ptr()`" when the type involved is a `CStr` or a `CString`.

Co-authored-by: Jieyou Xu <jieyouxu@outlook.com>
This commit is contained in:
Flying-Toast 2024-03-23 10:49:05 -04:00 committed by 许杰友 Jieyou Xu (Joe)
parent 93ea767e29
commit b335ec9ec8
7 changed files with 172 additions and 21 deletions

View file

@ -1,21 +1,21 @@
warning: `extern` fn uses type `[i8 or u8 (arch dependant)]`, which is not FFI-safe
warning: `extern` fn uses type `CStr`, which is not FFI-safe
--> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:7:12
|
LL | type Foo = extern "C" fn(::std::ffi::CStr);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
= help: consider using a raw pointer instead
= note: slices have no C equivalent
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
= note: `#[warn(improper_ctypes_definitions)]` on by default
warning: `extern` block uses type `[i8 or u8 (arch dependant)]`, which is not FFI-safe
warning: `extern` block uses type `CStr`, which is not FFI-safe
--> $DIR/extern-C-non-FFI-safe-arg-ice-52334.rs:10:18
|
LL | fn meh(blah: Foo);
| ^^^ not FFI-safe
|
= help: consider using a raw pointer instead
= note: slices have no C equivalent
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
= note: `#[warn(improper_ctypes)]` on by default
warning: 2 warnings emitted

View file

@ -0,0 +1,36 @@
#![crate_type = "lib"]
#![deny(improper_ctypes, improper_ctypes_definitions)]
use std::ffi::{CStr, CString};
extern "C" {
fn take_cstr(s: CStr);
//~^ ERROR `extern` block uses type `CStr`, which is not FFI-safe
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
fn take_cstr_ref(s: &CStr);
//~^ ERROR `extern` block uses type `CStr`, which is not FFI-safe
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
fn take_cstring(s: CString);
//~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
fn take_cstring_ref(s: &CString);
//~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
fn no_special_help_for_mut_cstring(s: *mut CString);
//~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
//~| HELP consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
fn no_special_help_for_mut_cstring_ref(s: &mut CString);
//~^ ERROR `extern` block uses type `CString`, which is not FFI-safe
//~| HELP consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
}
extern "C" fn rust_take_cstr_ref(s: &CStr) {}
//~^ ERROR `extern` fn uses type `CStr`, which is not FFI-safe
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
extern "C" fn rust_take_cstring(s: CString) {}
//~^ ERROR `extern` fn uses type `CString`, which is not FFI-safe
//~| HELP consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
extern "C" fn rust_no_special_help_for_mut_cstring(s: *mut CString) {}
extern "C" fn rust_no_special_help_for_mut_cstring_ref(s: &mut CString) {}

View file

@ -0,0 +1,84 @@
error: `extern` block uses type `CStr`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:7:21
|
LL | fn take_cstr(s: CStr);
| ^^^^ not FFI-safe
|
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
note: the lint level is defined here
--> $DIR/lint-ctypes-cstr.rs:2:9
|
LL | #![deny(improper_ctypes, improper_ctypes_definitions)]
| ^^^^^^^^^^^^^^^
error: `extern` block uses type `CStr`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:10:25
|
LL | fn take_cstr_ref(s: &CStr);
| ^^^^^ not FFI-safe
|
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
error: `extern` block uses type `CString`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:13:24
|
LL | fn take_cstring(s: CString);
| ^^^^^^^ not FFI-safe
|
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
error: `extern` block uses type `CString`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:16:28
|
LL | fn take_cstring_ref(s: &CString);
| ^^^^^^^^ not FFI-safe
|
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
error: `extern` block uses type `CString`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:20:43
|
LL | fn no_special_help_for_mut_cstring(s: *mut CString);
| ^^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
error: `extern` block uses type `CString`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:24:47
|
LL | fn no_special_help_for_mut_cstring_ref(s: &mut CString);
| ^^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
= note: this struct has unspecified layout
error: `extern` fn uses type `CStr`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:29:37
|
LL | extern "C" fn rust_take_cstr_ref(s: &CStr) {}
| ^^^^^ not FFI-safe
|
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
note: the lint level is defined here
--> $DIR/lint-ctypes-cstr.rs:2:26
|
LL | #![deny(improper_ctypes, improper_ctypes_definitions)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `extern` fn uses type `CString`, which is not FFI-safe
--> $DIR/lint-ctypes-cstr.rs:32:36
|
LL | extern "C" fn rust_take_cstring(s: CString) {}
| ^^^^^^^ not FFI-safe
|
= help: consider passing a `*const std::ffi::c_char` instead, and use `CStr::as_ptr()`
= note: `CStr`/`CString` do not have a guaranteed layout
error: aborting due to 8 previous errors