summaryrefslogtreecommitdiffstats
path: root/src/test/ui/lint/clashing-extern-fn.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/lint/clashing-extern-fn.rs')
-rw-r--r--src/test/ui/lint/clashing-extern-fn.rs417
1 files changed, 0 insertions, 417 deletions
diff --git a/src/test/ui/lint/clashing-extern-fn.rs b/src/test/ui/lint/clashing-extern-fn.rs
deleted file mode 100644
index 809e06026..000000000
--- a/src/test/ui/lint/clashing-extern-fn.rs
+++ /dev/null
@@ -1,417 +0,0 @@
-// check-pass
-// aux-build:external_extern_fn.rs
-#![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;
-mod extern_no_clash {
- // Should not clash with external_extern_fn::extern_fn.
- extern "C" {
- fn extern_fn(x: u8);
- }
-}
-
-extern "C" {
- fn some_other_new_name(x: i16);
-
- #[link_name = "extern_link_name"]
- fn some_new_name(x: i16);
-
- #[link_name = "link_name_same"]
- fn both_names_different(x: i16);
-}
-
-fn link_name_clash() {
- extern "C" {
- fn extern_link_name(x: u32);
- //~^ WARN `extern_link_name` redeclared with a different signature
-
- #[link_name = "some_other_new_name"]
- //~^ WARN `some_other_extern_link_name` redeclares `some_other_new_name` with a different
- fn some_other_extern_link_name(x: u32);
-
- #[link_name = "link_name_same"]
- //~^ WARN `other_both_names_different` redeclares `link_name_same` with a different
- fn other_both_names_different(x: u32);
- }
-}
-
-mod a {
- extern "C" {
- fn different_mod(x: u8);
- }
-}
-mod b {
- extern "C" {
- fn different_mod(x: u64); //~ WARN `different_mod` redeclared with a different signature
- }
-}
-
-extern "C" {
- fn variadic_decl(x: u8, ...);
-}
-
-fn variadic_clash() {
- extern "C" {
- fn variadic_decl(x: u8); //~ WARN `variadic_decl` redeclared with a different signature
- }
-}
-
-#[no_mangle]
-fn no_mangle_name(x: u8) {}
-
-extern "C" {
- #[link_name = "unique_link_name"]
- fn link_name_specified(x: u8);
-}
-
-fn tricky_no_clash() {
- extern "C" {
- // Shouldn't warn, because the declaration above actually declares a different symbol (and
- // Rust's name resolution rules around shadowing will handle this gracefully).
- fn link_name_specified() -> u32;
-
- // The case of a no_mangle name colliding with an extern decl (see #28179) is related but
- // shouldn't be reported by ClashingExternDeclarations, because this is an example of
- // unmangled name clash causing bad behaviour in functions with a defined body.
- fn no_mangle_name() -> u32;
- }
-}
-
-mod banana {
- mod one {
- #[repr(C)]
- struct Banana {
- weight: u32,
- length: u16,
- }
- extern "C" {
- fn weigh_banana(count: *const Banana) -> u64;
- }
- }
-
- mod two {
- #[repr(C)]
- struct Banana {
- weight: u32,
- length: u16,
- } // note: distinct type
- // This should not trigger the lint because two::Banana is structurally equivalent to
- // one::Banana.
- extern "C" {
- fn weigh_banana(count: *const Banana) -> u64;
- }
- }
-
- mod three {
- // This _should_ trigger the lint, because repr(packed) should generate a struct that has a
- // different layout.
- #[repr(packed)]
- struct Banana {
- weight: u32,
- length: u16,
- }
- #[allow(improper_ctypes)]
- extern "C" {
- fn weigh_banana(count: *const Banana) -> u64;
- //~^ WARN `weigh_banana` redeclared with a different signature
- }
- }
-}
-
-mod sameish_members {
- mod a {
- #[repr(C)]
- struct Point {
- x: i16,
- y: i16,
- }
-
- extern "C" {
- fn draw_point(p: Point);
- }
- }
- mod b {
- #[repr(C)]
- struct Point {
- coordinates: [i16; 2],
- }
-
- // It's possible we are overconservative for this case, as accessing the elements of the
- // coordinates array might end up correctly accessing `.x` and `.y`. However, this may not
- // 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 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
- }
- }
-}
-
-// See #75739
-mod non_zero_transparent {
- mod a1 {
- use std::num::NonZeroUsize;
- extern "C" {
- fn f1() -> NonZeroUsize;
- }
- }
-
- mod b1 {
- #[repr(transparent)]
- struct X(NonZeroUsize);
- use std::num::NonZeroUsize;
- extern "C" {
- fn f1() -> X;
- }
- }
-
- mod a2 {
- use std::num::NonZeroUsize;
- extern "C" {
- fn f2() -> NonZeroUsize;
- }
- }
-
- mod b2 {
- #[repr(transparent)]
- struct X1(NonZeroUsize);
-
- #[repr(transparent)]
- struct X(X1);
-
- use std::num::NonZeroUsize;
- extern "C" {
- // Same case as above, but with two layers of newtyping.
- fn f2() -> X;
- }
- }
-
- mod a3 {
- #[repr(transparent)]
- struct X(core::ptr::NonNull<i32>);
-
- use std::num::NonZeroUsize;
- extern "C" {
- fn f3() -> X;
- }
- }
-
- mod b3 {
- extern "C" {
- fn f3() -> core::ptr::NonNull<i32>;
- }
- }
-
- mod a4 {
- #[repr(transparent)]
- enum E {
- X(std::num::NonZeroUsize),
- }
- extern "C" {
- fn f4() -> E;
- }
- }
-
- mod b4 {
- extern "C" {
- fn f4() -> std::num::NonZeroUsize;
- }
- }
-}
-
-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
- }
- }
-}
-
-#[allow(improper_ctypes)]
-mod unknown_layout {
- mod a {
- extern "C" {
- pub fn generic(l: Link<u32>);
- }
- pub struct Link<T> {
- pub item: T,
- pub next: *const Link<T>,
- }
- }
-
- mod b {
- extern "C" {
- pub fn generic(l: Link<u32>);
- }
- pub struct Link<T> {
- pub item: T,
- pub next: *const Link<T>,
- }
- }
-}
-
-mod hidden_niche {
- mod a {
- extern "C" {
- fn hidden_niche_transparent() -> usize;
- fn hidden_niche_transparent_no_niche() -> usize;
- fn hidden_niche_unsafe_cell() -> usize;
- }
- }
- mod b {
- use std::cell::UnsafeCell;
- use std::num::NonZeroUsize;
-
- #[repr(transparent)]
- struct Transparent { x: NonZeroUsize }
-
- #[repr(transparent)]
- struct TransparentNoNiche { y: UnsafeCell<NonZeroUsize> }
-
- extern "C" {
- fn hidden_niche_transparent() -> Option<Transparent>;
-
- fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>;
- //~^ WARN redeclared with a different signature
- //~| WARN block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
-
- fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
- //~^ WARN redeclared with a different signature
- //~| WARN block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe
- }
- }
-}