diff --git a/src/test/ui/lint/auxiliary/external_extern_fn.rs b/src/test/ui/lint/auxiliary/external_extern_fn.rs index b2caebc6fee..c2a8cadc6b5 100644 --- a/src/test/ui/lint/auxiliary/external_extern_fn.rs +++ b/src/test/ui/lint/auxiliary/external_extern_fn.rs @@ -1,3 +1,3 @@ -extern { +extern "C" { pub fn extern_fn(x: u8); } diff --git a/src/test/ui/lint/clashing-extern-fn.rs b/src/test/ui/lint/clashing-extern-fn.rs index 544614100ba..72c5d3da4b0 100644 --- a/src/test/ui/lint/clashing-extern-fn.rs +++ b/src/test/ui/lint/clashing-extern-fn.rs @@ -3,52 +3,40 @@ #![crate_type = "lib"] #![warn(clashing_extern_declarations)] +mod redeclared_different_signature { + mod a { + extern "C" { + fn clash(x: u8); + } + } + mod b { + extern "C" { + fn clash(x: u64); //~ WARN `clash` redeclared with a different signature + } + } +} + +mod redeclared_same_signature { + mod a { + extern "C" { + fn no_clash(x: u8); + } + } + mod b { + extern "C" { + fn no_clash(x: u8); + } + } +} + extern crate external_extern_fn; - -extern "C" { - fn clash(x: u8); - fn no_clash(x: u8); -} - -fn redeclared_different_signature() { +mod extern_no_clash { + // Should not clash with external_extern_fn::extern_fn. extern "C" { - fn clash(x: u64); //~ WARN `clash` redeclared with a different signature - } - - unsafe { - clash(123); - no_clash(123); + fn extern_fn(x: u8); } } -fn redeclared_same_signature() { - extern "C" { - fn no_clash(x: u8); - } - unsafe { - no_clash(123); - } -} - -extern "C" { - fn extern_fn(x: u64); -} - -fn extern_clash() { - extern "C" { - fn extern_fn(x: u32); //~ WARN `extern_fn` redeclared with a different signature - } - unsafe { - extern_fn(123); - } -} - -fn extern_no_clash() { - unsafe { - external_extern_fn::extern_fn(123); - crate::extern_fn(123); - } -} extern "C" { fn some_other_new_name(x: i16); @@ -134,9 +122,9 @@ mod banana { weight: u32, length: u16, } // note: distinct type - extern "C" { // This should not trigger the lint because two::Banana is structurally equivalent to // one::Banana. + extern "C" { fn weigh_banana(count: *const Banana) -> u64; } } @@ -180,7 +168,93 @@ mod sameish_members { // always be the case, for every architecture and situation. This is also a really odd // thing to do anyway. extern "C" { - fn draw_point(p: Point); //~ WARN `draw_point` redeclared with a different + fn draw_point(p: Point); + //~^ WARN `draw_point` redeclared with a different signature + } + } +} + +mod transparent { + #[repr(transparent)] + struct T(usize); + mod a { + use super::T; + extern "C" { + fn transparent() -> T; + } + } + + mod b { + extern "C" { + // Shouldn't warn here, because repr(transparent) guarantees that T's layout is the + // same as just the usize. + fn transparent() -> usize; + } + } +} + +mod missing_return_type { + mod a { + extern "C" { + fn missing_return_type() -> usize; + } + } + + mod b { + extern "C" { + // This should warn, because we can't assume that the first declaration is the correct + // one -- if this one is the correct one, then calling the usize-returning version + // would allow reads into uninitialised memory. + fn missing_return_type(); + //~^ WARN `missing_return_type` redeclared with a different signature + } + } +} + +mod non_zero_and_non_null { + mod a { + extern "C" { + fn non_zero_usize() -> core::num::NonZeroUsize; + fn non_null_ptr() -> core::ptr::NonNull; + } + } + mod b { + extern "C" { + // For both of these cases, if there's a clash, you're either gaining an incorrect + // invariant that the value is non-zero, or you're missing out on that invariant. Both + // cases are warning for, from both a caller-convenience and optimisation perspective. + fn non_zero_usize() -> usize; + //~^ WARN `non_zero_usize` redeclared with a different signature + fn non_null_ptr() -> *const usize; + //~^ WARN `non_null_ptr` redeclared with a different signature + } + } +} + +mod null_optimised_enums { + mod a { + extern "C" { + fn option_non_zero_usize() -> usize; + fn option_non_zero_isize() -> isize; + fn option_non_null_ptr() -> *const usize; + + fn option_non_zero_usize_incorrect() -> usize; + fn option_non_null_ptr_incorrect() -> *const usize; + } + } + mod b { + extern "C" { + // This should be allowed, because these conversions are guaranteed to be FFI-safe (see + // #60300) + fn option_non_zero_usize() -> Option; + fn option_non_zero_isize() -> Option; + fn option_non_null_ptr() -> Option>; + + // However, these should be incorrect (note isize instead of usize) + fn option_non_zero_usize_incorrect() -> isize; + //~^ WARN `option_non_zero_usize_incorrect` redeclared with a different signature + fn option_non_null_ptr_incorrect() -> *const isize; + //~^ WARN `option_non_null_ptr_incorrect` redeclared with a different signature } } } diff --git a/src/test/ui/lint/clashing-extern-fn.stderr b/src/test/ui/lint/clashing-extern-fn.stderr index 96e51ab5a3e..a2aaaba7173 100644 --- a/src/test/ui/lint/clashing-extern-fn.stderr +++ b/src/test/ui/lint/clashing-extern-fn.stderr @@ -1,11 +1,11 @@ warning: `clash` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:15:9 + --> $DIR/clashing-extern-fn.rs:14:13 | -LL | fn clash(x: u8); - | ---------------- `clash` previously declared here +LL | fn clash(x: u8); + | ---------------- `clash` previously declared here ... -LL | fn clash(x: u64); - | ^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration +LL | fn clash(x: u64); + | ^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | note: the lint level is defined here --> $DIR/clashing-extern-fn.rs:4:9 @@ -15,20 +15,8 @@ LL | #![warn(clashing_extern_declarations)] = note: expected `unsafe extern "C" fn(u8)` found `unsafe extern "C" fn(u64)` -warning: `extern_fn` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:39:9 - | -LL | fn extern_fn(x: u64); - | --------------------- `extern_fn` previously declared here -... -LL | fn extern_fn(x: u32); - | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration - | - = note: expected `unsafe extern "C" fn(u64)` - found `unsafe extern "C" fn(u32)` - warning: `extern_link_name` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:64:9 + --> $DIR/clashing-extern-fn.rs:52:9 | LL | / #[link_name = "extern_link_name"] LL | | fn some_new_name(x: i16); @@ -41,7 +29,7 @@ LL | fn extern_link_name(x: u32); found `unsafe extern "C" fn(u32)` warning: `some_other_extern_link_name` redeclares `some_other_new_name` with a different signature - --> $DIR/clashing-extern-fn.rs:67:9 + --> $DIR/clashing-extern-fn.rs:55:9 | LL | fn some_other_new_name(x: i16); | ------------------------------- `some_other_new_name` previously declared here @@ -55,7 +43,7 @@ LL | | fn some_other_extern_link_name(x: u32); found `unsafe extern "C" fn(u32)` warning: `other_both_names_different` redeclares `link_name_same` with a different signature - --> $DIR/clashing-extern-fn.rs:71:9 + --> $DIR/clashing-extern-fn.rs:59:9 | LL | / #[link_name = "link_name_same"] LL | | fn both_names_different(x: i16); @@ -70,7 +58,7 @@ LL | | fn other_both_names_different(x: u32); found `unsafe extern "C" fn(u32)` warning: `different_mod` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:84:9 + --> $DIR/clashing-extern-fn.rs:72:9 | LL | fn different_mod(x: u8); | ------------------------ `different_mod` previously declared here @@ -82,7 +70,7 @@ LL | fn different_mod(x: u64); found `unsafe extern "C" fn(u64)` warning: `variadic_decl` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:94:9 + --> $DIR/clashing-extern-fn.rs:82:9 | LL | fn variadic_decl(x: u8, ...); | ----------------------------- `variadic_decl` previously declared here @@ -94,7 +82,7 @@ LL | fn variadic_decl(x: u8); found `unsafe extern "C" fn(u8)` warning: `weigh_banana` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:154:13 + --> $DIR/clashing-extern-fn.rs:142:13 | LL | fn weigh_banana(count: *const Banana) -> u64; | --------------------------------------------- `weigh_banana` previously declared here @@ -106,7 +94,7 @@ LL | fn weigh_banana(count: *const Banana) -> u64; found `unsafe extern "C" fn(*const banana::three::Banana) -> u64` warning: `draw_point` redeclared with a different signature - --> $DIR/clashing-extern-fn.rs:183:13 + --> $DIR/clashing-extern-fn.rs:171:13 | LL | fn draw_point(p: Point); | ------------------------ `draw_point` previously declared here @@ -117,5 +105,5 @@ LL | fn draw_point(p: Point); = note: expected `unsafe extern "C" fn(sameish_members::a::Point)` found `unsafe extern "C" fn(sameish_members::b::Point)` -warning: 9 warnings emitted +warning: 8 warnings emitted