diff options
| author | bors <bors@rust-lang.org> | 2020-07-30 14:36:41 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-07-30 14:36:41 +0000 |
| commit | 6b09c37ddc240e25748e53d7a8f81f252def6dee (patch) | |
| tree | cf776af8e0a57ff674b2828f93a0ceb5bdc002f0 /src/test/ui | |
| parent | 21867225a74d3b07c2b65e32c67f45197db36896 (diff) | |
| parent | 0bd292dea1a8f6e60ac8957ac0fcd0d237034918 (diff) | |
| download | rust-6b09c37ddc240e25748e53d7a8f81f252def6dee.tar.gz rust-6b09c37ddc240e25748e53d7a8f81f252def6dee.zip | |
Auto merge of #73990 - jumbatm:clashing-extern-decl, r=nagisa
Fix incorrect clashing_extern_declarations warnings. Fixes #73735, fixes #73872. Fix clashing_extern_declarations warning for `#[repr(transparent)]` structs and safely-FFI-convertible enums, and not warning for clashes of struct members of different types, but the same size. r? @nagisa
Diffstat (limited to 'src/test/ui')
| -rw-r--r-- | src/test/ui/lint/auxiliary/external_extern_fn.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/lint/clashing-extern-fn.rs | 173 | ||||
| -rw-r--r-- | src/test/ui/lint/clashing-extern-fn.stderr | 122 |
3 files changed, 235 insertions, 62 deletions
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..d6ac7ccccc7 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)] -extern crate external_extern_fn; - -extern "C" { - fn clash(x: u8); - fn no_clash(x: u8); -} - -fn redeclared_different_signature() { - extern "C" { - fn clash(x: u64); //~ WARN `clash` redeclared with a different signature +mod redeclared_different_signature { + mod a { + extern "C" { + fn clash(x: u8); + } } - - unsafe { - clash(123); - no_clash(123); + mod b { + extern "C" { + fn clash(x: u64); //~ WARN `clash` redeclared with a different signature + } } } -fn redeclared_same_signature() { - extern "C" { - fn no_clash(x: u8); +mod redeclared_same_signature { + mod a { + extern "C" { + fn no_clash(x: u8); + } } - unsafe { - no_clash(123); + mod b { + extern "C" { + fn no_clash(x: u8); + } } } -extern "C" { - fn extern_fn(x: u64); -} - -fn extern_clash() { +extern crate external_extern_fn; +mod extern_no_clash { + // Should not clash with external_extern_fn::extern_fn. extern "C" { - fn extern_fn(x: u32); //~ WARN `extern_fn` redeclared with a different signature - } - unsafe { - extern_fn(123); + fn extern_fn(x: u8); } } -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,120 @@ 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 same_sized_members_clash { + mod a { + #[repr(C)] + struct Point3 { + x: f32, + y: f32, + z: f32, + } + extern "C" { fn origin() -> Point3; } + } + mod b { + #[repr(C)] + struct Point3 { + x: i32, + y: i32, + z: i32, // NOTE: Incorrectly redeclared as i32 + } + extern "C" { fn origin() -> Point3; } + //~^ WARN `origin` redeclared with a different signature + } +} + +mod transparent { + #[repr(transparent)] + struct T(usize); + mod a { + use super::T; + extern "C" { + fn transparent() -> T; + fn transparent_incorrect() -> 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; + + // Should warn, because there's a signedness conversion here: + fn transparent_incorrect() -> isize; + //~^ WARN `transparent_incorrect` redeclared with a different signature + } + } +} + +mod missing_return_type { + mod a { + extern "C" { + fn missing_return_type() -> usize; + } + } + + mod b { + extern "C" { + // This should output a warning 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<usize>; + } + } + mod b { + extern "C" { + // If there's a clash in either of these cases 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<core::num::NonZeroUsize>; + fn option_non_zero_isize() -> Option<core::num::NonZeroIsize>; + fn option_non_null_ptr() -> Option<core::ptr::NonNull<usize>>; + + // 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..cca0c4c59eb 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,89 @@ 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: `origin` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:194:22 + | +LL | extern "C" { fn origin() -> Point3; } + | ---------------------- `origin` previously declared here +... +LL | extern "C" { fn origin() -> Point3; } + | ^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> same_sized_members_clash::a::Point3` + found `unsafe extern "C" fn() -> same_sized_members_clash::b::Point3` + +warning: `transparent_incorrect` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:217:13 + | +LL | fn transparent_incorrect() -> T; + | -------------------------------- `transparent_incorrect` previously declared here +... +LL | fn transparent_incorrect() -> isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> transparent::T` + found `unsafe extern "C" fn() -> isize` + +warning: `missing_return_type` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:235:13 + | +LL | fn missing_return_type() -> usize; + | ---------------------------------- `missing_return_type` previously declared here +... +LL | fn missing_return_type(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> usize` + found `unsafe extern "C" fn()` + +warning: `non_zero_usize` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:253:13 + | +LL | fn non_zero_usize() -> core::num::NonZeroUsize; + | ----------------------------------------------- `non_zero_usize` previously declared here +... +LL | fn non_zero_usize() -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> std::num::NonZeroUsize` + found `unsafe extern "C" fn() -> usize` + +warning: `non_null_ptr` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:255:13 + | +LL | fn non_null_ptr() -> core::ptr::NonNull<usize>; + | ----------------------------------------------- `non_null_ptr` previously declared here +... +LL | fn non_null_ptr() -> *const usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> std::ptr::NonNull<usize>` + found `unsafe extern "C" fn() -> *const usize` + +warning: `option_non_zero_usize_incorrect` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:281:13 + | +LL | fn option_non_zero_usize_incorrect() -> usize; + | ---------------------------------------------- `option_non_zero_usize_incorrect` previously declared here +... +LL | fn option_non_zero_usize_incorrect() -> isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> usize` + found `unsafe extern "C" fn() -> isize` + +warning: `option_non_null_ptr_incorrect` redeclared with a different signature + --> $DIR/clashing-extern-fn.rs:283:13 + | +LL | fn option_non_null_ptr_incorrect() -> *const usize; + | --------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here +... +LL | fn option_non_null_ptr_incorrect() -> *const isize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration + | + = note: expected `unsafe extern "C" fn() -> *const usize` + found `unsafe extern "C" fn() -> *const isize` + +warning: 15 warnings emitted |
