lint ImproperCTypes: confirm that Box<FfiSafeType> and Option<Box<FfiSafeType>> are FFI-safe in function declarations too

This commit is contained in:
niacdoial 2024-11-10 01:38:54 +01:00
parent d857bc8fbb
commit 9b59dd8178
3 changed files with 27 additions and 63 deletions

View file

@ -866,7 +866,7 @@ fn ty_is_known_nonnull<'tcx>(
match ty.kind() {
ty::FnPtr(..) => true,
ty::Ref(..) => true,
ty::Adt(def, _) if def.is_box() && matches!(mode, CItemKind::Definition) => true,
ty::Adt(def, _) if def.is_box() => true,
ty::Adt(def, args) if def.repr().transparent() && !def.is_union() => {
let marked_non_null = nonnull_optimization_guaranteed(tcx, *def);

View file

@ -23,7 +23,7 @@ pub type I32Pair = (i32, i32);
#[repr(C)]
pub struct ZeroSize;
pub type RustFn = fn();
pub type RustBadRet = extern "C" fn() -> Box<u32>;
pub type RustBoxRet = extern "C" fn() -> Box<u32>;
pub type CVoidRet = ();
pub struct Foo;
#[repr(transparent)]
@ -31,7 +31,7 @@ pub struct TransparentI128(i128);
#[repr(transparent)]
pub struct TransparentStr(&'static str);
#[repr(transparent)]
pub struct TransparentBadFn(RustBadRet);
pub struct TransparentBoxFn(RustBoxRet);
#[repr(transparent)]
pub struct TransparentInt(u32);
#[repr(transparent)]
@ -63,9 +63,8 @@ extern "C" {
pub fn ptr_tuple(p: *const ((),)); //~ ERROR: uses type `((),)`
pub fn slice_type(p: &[u32]); //~ ERROR: uses type `&[u32]`
pub fn str_type(p: &str); //~ ERROR: uses type `&str`
pub fn box_type(p: Box<u32>); //~ ERROR uses type `Box<u32>`
pub fn box_type(p: Box<u32>);
pub fn opt_box_type(p: Option<Box<u32>>);
//~^ ERROR uses type `Option<Box<u32>>`
pub fn char_type(p: char); //~ ERROR uses type `char`
pub fn i128_type(p: i128); //~ ERROR uses type `i128`
pub fn u128_type(p: u128); //~ ERROR uses type `u128`
@ -79,10 +78,10 @@ extern "C" {
-> ::std::marker::PhantomData<bool>; //~ ERROR uses type `PhantomData<bool>`
pub fn fn_type(p: RustFn); //~ ERROR uses type `fn()`
pub fn fn_type2(p: fn()); //~ ERROR uses type `fn()`
pub fn fn_contained(p: RustBadRet); //~ ERROR: uses type `Box<u32>`
pub fn fn_contained(p: RustBoxRet);
pub fn transparent_i128(p: TransparentI128); //~ ERROR: uses type `i128`
pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `&str`
pub fn transparent_fn(p: TransparentBadFn); //~ ERROR: uses type `Box<u32>`
pub fn transparent_fn(p: TransparentBoxFn);
pub fn raw_array(arr: [u8; 8]); //~ ERROR: uses type `[u8; 8]`
pub fn struct_unsized_ptr_no_metadata(p: &UnsizedStructBecauseForeign);

View file

@ -61,26 +61,8 @@ LL | pub fn str_type(p: &str);
= help: consider using `*const u8` and a length instead
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:53:24
|
LL | pub fn box_type(p: Box<u32>);
| ^^^^^^^^ 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 `Option<Box<u32>>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:67:28
|
LL | pub fn opt_box_type(p: Option<Box<u32>>);
| ^^^^^^^^^^^^^^^^ not FFI-safe
|
= help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
= note: enum has no representation hint
error: `extern` block uses type `char`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:69:25
--> $DIR/lint-ctypes.rs:68:25
|
LL | pub fn char_type(p: char);
| ^^^^ not FFI-safe
@ -89,7 +71,7 @@ LL | pub fn char_type(p: char);
= note: the `char` type has no C equivalent
error: `extern` block uses type `i128`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:70:25
--> $DIR/lint-ctypes.rs:69:25
|
LL | pub fn i128_type(p: i128);
| ^^^^ not FFI-safe
@ -97,7 +79,7 @@ LL | pub fn i128_type(p: i128);
= note: 128-bit integers don't currently have a known stable ABI
error: `extern` block uses type `u128`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:71:25
--> $DIR/lint-ctypes.rs:70:25
|
LL | pub fn u128_type(p: u128);
| ^^^^ not FFI-safe
@ -105,7 +87,7 @@ LL | pub fn u128_type(p: u128);
= note: 128-bit integers don't currently have a known stable ABI
error: `extern` block uses type `&dyn Bar`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:72:26
--> $DIR/lint-ctypes.rs:71:26
|
LL | pub fn trait_type(p: &dyn Bar);
| ^^^^^^^^ not FFI-safe
@ -113,7 +95,7 @@ LL | pub fn trait_type(p: &dyn Bar);
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:73:26
--> $DIR/lint-ctypes.rs:72:26
|
LL | pub fn tuple_type(p: (i32, i32));
| ^^^^^^^^^^ not FFI-safe
@ -122,7 +104,7 @@ LL | pub fn tuple_type(p: (i32, i32));
= note: tuples have unspecified layout
error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:74:27
--> $DIR/lint-ctypes.rs:73:27
|
LL | pub fn tuple_type2(p: I32Pair);
| ^^^^^^^ not FFI-safe
@ -131,7 +113,7 @@ LL | pub fn tuple_type2(p: I32Pair);
= note: tuples have unspecified layout
error: `extern` block uses type `ZeroSize`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:75:25
--> $DIR/lint-ctypes.rs:74:25
|
LL | pub fn zero_size(p: ZeroSize);
| ^^^^^^^^ not FFI-safe
@ -145,7 +127,7 @@ LL | pub struct ZeroSize;
| ^^^^^^^^^^^^^^^^^^^
error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:76:33
--> $DIR/lint-ctypes.rs:75:33
|
LL | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
| ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -158,7 +140,7 @@ LL | pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `extern` block uses type `PhantomData<bool>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:79:12
--> $DIR/lint-ctypes.rs:78:12
|
LL | -> ::std::marker::PhantomData<bool>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -166,7 +148,7 @@ LL | -> ::std::marker::PhantomData<bool>;
= note: composed only of `PhantomData`
error: `extern` block uses type `fn()`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:80:23
--> $DIR/lint-ctypes.rs:79:23
|
LL | pub fn fn_type(p: RustFn);
| ^^^^^^ not FFI-safe
@ -175,7 +157,7 @@ LL | pub fn fn_type(p: RustFn);
= note: this function pointer has Rust-specific calling convention
error: `extern` block uses type `fn()`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:81:24
--> $DIR/lint-ctypes.rs:80:24
|
LL | pub fn fn_type2(p: fn());
| ^^^^ not FFI-safe
@ -183,17 +165,8 @@ LL | pub fn fn_type2(p: fn());
= help: consider using an `extern fn(...) -> ...` function pointer instead
= note: this function pointer has Rust-specific calling convention
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:69:28
|
LL | pub fn fn_contained(p: RustBadRet);
| ^^^^^^^^^^ 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 `i128`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:83:32
--> $DIR/lint-ctypes.rs:82:32
|
LL | pub fn transparent_i128(p: TransparentI128);
| ^^^^^^^^^^^^^^^ not FFI-safe
@ -201,7 +174,7 @@ LL | pub fn transparent_i128(p: TransparentI128);
= note: 128-bit integers don't currently have a known stable ABI
error: `extern` block uses type `&str`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:84:31
--> $DIR/lint-ctypes.rs:83:31
|
LL | pub fn transparent_str(p: TransparentStr);
| ^^^^^^^^^^^^^^ not FFI-safe
@ -209,17 +182,8 @@ LL | pub fn transparent_str(p: TransparentStr);
= help: consider using `*const u8` and a length instead
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
error: `extern` block uses type `Box<u32>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:72:30
|
LL | pub fn transparent_fn(p: TransparentBadFn);
| ^^^^^^^^^^^^^^^^ 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 `[u8; 8]`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:86:27
--> $DIR/lint-ctypes.rs:85:27
|
LL | pub fn raw_array(arr: [u8; 8]);
| ^^^^^^^ not FFI-safe
@ -228,7 +192,7 @@ LL | pub fn raw_array(arr: [u8; 8]);
= note: passing raw arrays by value is not FFI-safe
error: `extern` block uses type `&UnsizedStructBecauseDyn`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:89:47
--> $DIR/lint-ctypes.rs:88:47
|
LL | pub fn struct_unsized_ptr_has_metadata(p: &UnsizedStructBecauseDyn);
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -236,7 +200,7 @@ LL | pub fn struct_unsized_ptr_has_metadata(p: &UnsizedStructBecauseDyn);
= note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer
error: `extern` block uses type `Option<UnsafeCell<extern "C" fn()>>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:91:26
--> $DIR/lint-ctypes.rs:90:26
|
LL | pub fn no_niche_a(a: Option<UnsafeCell<extern fn()>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -245,7 +209,7 @@ LL | pub fn no_niche_a(a: Option<UnsafeCell<extern fn()>>);
= note: enum has no representation hint
error: `extern` block uses type `Option<UnsafeCell<&i32>>`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:93:26
--> $DIR/lint-ctypes.rs:92:26
|
LL | pub fn no_niche_b(b: Option<UnsafeCell<&i32>>);
| ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@ -254,7 +218,7 @@ LL | pub fn no_niche_b(b: Option<UnsafeCell<&i32>>);
= note: enum has no representation hint
error: `extern` block uses type `u128`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:96:34
--> $DIR/lint-ctypes.rs:95:34
|
LL | pub static static_u128_type: u128;
| ^^^^ not FFI-safe
@ -262,11 +226,12 @@ LL | pub static static_u128_type: u128;
= note: 128-bit integers don't currently have a known stable ABI
error: `extern` block uses type `u128`, which is not FFI-safe
--> $DIR/lint-ctypes.rs:97:40
--> $DIR/lint-ctypes.rs:96:40
|
LL | pub static static_u128_array_type: [u128; 16];
| ^^^^^^^^^^ not FFI-safe
|
= note: 128-bit integers don't currently have a known stable ABI
error: aborting due to 29 previous errors
error: aborting due to 24 previous errors