about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorFlying-Toast <38232168+Flying-Toast@users.noreply.github.com>2024-03-23 10:49:05 -0400
committer许杰友 Jieyou Xu (Joe) <jieyouxu@outlook.com>2024-08-06 13:56:59 +0000
commitb335ec9ec8d1132efee4e900a1c173efc7f4a357 (patch)
treecb0683b9e2c6672f3a079c4b54e55ac5693e9604 /tests
parent93ea767e2928589b74296ba85b57d80e108db712 (diff)
downloadrust-b335ec9ec8d1132efee4e900a1c173efc7f4a357.tar.gz
rust-b335ec9ec8d1132efee4e900a1c173efc7f4a357.zip
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>
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr12
-rw-r--r--tests/ui/lint/lint-ctypes-cstr.rs36
-rw-r--r--tests/ui/lint/lint-ctypes-cstr.stderr84
3 files changed, 126 insertions, 6 deletions
diff --git a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr
index 83492988479..044c1ae2dd4 100644
--- a/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr
+++ b/tests/ui/extern/extern-C-non-FFI-safe-arg-ice-52334.stderr
@@ -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
diff --git a/tests/ui/lint/lint-ctypes-cstr.rs b/tests/ui/lint/lint-ctypes-cstr.rs
new file mode 100644
index 00000000000..b04decd0bca
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-cstr.rs
@@ -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) {}
diff --git a/tests/ui/lint/lint-ctypes-cstr.stderr b/tests/ui/lint/lint-ctypes-cstr.stderr
new file mode 100644
index 00000000000..8957758d577
--- /dev/null
+++ b/tests/ui/lint/lint-ctypes-cstr.stderr
@@ -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
+