Skip to content

Commit 4da72f5

Browse files
committed
Add additional clashing_extern_decl cases.
1 parent 1799d31 commit 4da72f5

File tree

3 files changed

+124
-62
lines changed

3 files changed

+124
-62
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
extern {
1+
extern "C" {
22
pub fn extern_fn(x: u8);
33
}

src/test/ui/lint/clashing-extern-fn.rs

Lines changed: 110 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,52 +3,40 @@
33
#![crate_type = "lib"]
44
#![warn(clashing_extern_declarations)]
55

6-
extern crate external_extern_fn;
7-
8-
extern "C" {
9-
fn clash(x: u8);
10-
fn no_clash(x: u8);
11-
}
12-
13-
fn redeclared_different_signature() {
14-
extern "C" {
15-
fn clash(x: u64); //~ WARN `clash` redeclared with a different signature
6+
mod redeclared_different_signature {
7+
mod a {
8+
extern "C" {
9+
fn clash(x: u8);
10+
}
1611
}
17-
18-
unsafe {
19-
clash(123);
20-
no_clash(123);
12+
mod b {
13+
extern "C" {
14+
fn clash(x: u64); //~ WARN `clash` redeclared with a different signature
15+
}
2116
}
2217
}
2318

24-
fn redeclared_same_signature() {
25-
extern "C" {
26-
fn no_clash(x: u8);
19+
mod redeclared_same_signature {
20+
mod a {
21+
extern "C" {
22+
fn no_clash(x: u8);
23+
}
2724
}
28-
unsafe {
29-
no_clash(123);
25+
mod b {
26+
extern "C" {
27+
fn no_clash(x: u8);
28+
}
3029
}
3130
}
3231

33-
extern "C" {
34-
fn extern_fn(x: u64);
35-
}
36-
37-
fn extern_clash() {
32+
extern crate external_extern_fn;
33+
mod extern_no_clash {
34+
// Should not clash with external_extern_fn::extern_fn.
3835
extern "C" {
39-
fn extern_fn(x: u32); //~ WARN `extern_fn` redeclared with a different signature
40-
}
41-
unsafe {
42-
extern_fn(123);
36+
fn extern_fn(x: u8);
4337
}
4438
}
4539

46-
fn extern_no_clash() {
47-
unsafe {
48-
external_extern_fn::extern_fn(123);
49-
crate::extern_fn(123);
50-
}
51-
}
5240
extern "C" {
5341
fn some_other_new_name(x: i16);
5442

@@ -134,9 +122,9 @@ mod banana {
134122
weight: u32,
135123
length: u16,
136124
} // note: distinct type
137-
extern "C" {
138125
// This should not trigger the lint because two::Banana is structurally equivalent to
139126
// one::Banana.
127+
extern "C" {
140128
fn weigh_banana(count: *const Banana) -> u64;
141129
}
142130
}
@@ -180,7 +168,93 @@ mod sameish_members {
180168
// always be the case, for every architecture and situation. This is also a really odd
181169
// thing to do anyway.
182170
extern "C" {
183-
fn draw_point(p: Point); //~ WARN `draw_point` redeclared with a different
171+
fn draw_point(p: Point);
172+
//~^ WARN `draw_point` redeclared with a different signature
173+
}
174+
}
175+
}
176+
177+
mod transparent {
178+
#[repr(transparent)]
179+
struct T(usize);
180+
mod a {
181+
use super::T;
182+
extern "C" {
183+
fn transparent() -> T;
184+
}
185+
}
186+
187+
mod b {
188+
extern "C" {
189+
// Shouldn't warn here, because repr(transparent) guarantees that T's layout is the
190+
// same as just the usize.
191+
fn transparent() -> usize;
192+
}
193+
}
194+
}
195+
196+
mod missing_return_type {
197+
mod a {
198+
extern "C" {
199+
fn missing_return_type() -> usize;
200+
}
201+
}
202+
203+
mod b {
204+
extern "C" {
205+
// This should warn, because we can't assume that the first declaration is the correct
206+
// one -- if this one is the correct one, then calling the usize-returning version
207+
// would allow reads into uninitialised memory.
208+
fn missing_return_type();
209+
//~^ WARN `missing_return_type` redeclared with a different signature
210+
}
211+
}
212+
}
213+
214+
mod non_zero_and_non_null {
215+
mod a {
216+
extern "C" {
217+
fn non_zero_usize() -> core::num::NonZeroUsize;
218+
fn non_null_ptr() -> core::ptr::NonNull<usize>;
219+
}
220+
}
221+
mod b {
222+
extern "C" {
223+
// For both of these cases, if there's a clash, you're either gaining an incorrect
224+
// invariant that the value is non-zero, or you're missing out on that invariant. Both
225+
// cases are warning for, from both a caller-convenience and optimisation perspective.
226+
fn non_zero_usize() -> usize;
227+
//~^ WARN `non_zero_usize` redeclared with a different signature
228+
fn non_null_ptr() -> *const usize;
229+
//~^ WARN `non_null_ptr` redeclared with a different signature
230+
}
231+
}
232+
}
233+
234+
mod null_optimised_enums {
235+
mod a {
236+
extern "C" {
237+
fn option_non_zero_usize() -> usize;
238+
fn option_non_zero_isize() -> isize;
239+
fn option_non_null_ptr() -> *const usize;
240+
241+
fn option_non_zero_usize_incorrect() -> usize;
242+
fn option_non_null_ptr_incorrect() -> *const usize;
243+
}
244+
}
245+
mod b {
246+
extern "C" {
247+
// This should be allowed, because these conversions are guaranteed to be FFI-safe (see
248+
// #60300)
249+
fn option_non_zero_usize() -> Option<core::num::NonZeroUsize>;
250+
fn option_non_zero_isize() -> Option<core::num::NonZeroIsize>;
251+
fn option_non_null_ptr() -> Option<core::ptr::NonNull<usize>>;
252+
253+
// However, these should be incorrect (note isize instead of usize)
254+
fn option_non_zero_usize_incorrect() -> isize;
255+
//~^ WARN `option_non_zero_usize_incorrect` redeclared with a different signature
256+
fn option_non_null_ptr_incorrect() -> *const isize;
257+
//~^ WARN `option_non_null_ptr_incorrect` redeclared with a different signature
184258
}
185259
}
186260
}

src/test/ui/lint/clashing-extern-fn.stderr

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
warning: `clash` redeclared with a different signature
2-
--> $DIR/clashing-extern-fn.rs:15:9
2+
--> $DIR/clashing-extern-fn.rs:14:13
33
|
4-
LL | fn clash(x: u8);
5-
| ---------------- `clash` previously declared here
4+
LL | fn clash(x: u8);
5+
| ---------------- `clash` previously declared here
66
...
7-
LL | fn clash(x: u64);
8-
| ^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
7+
LL | fn clash(x: u64);
8+
| ^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
99
|
1010
note: the lint level is defined here
1111
--> $DIR/clashing-extern-fn.rs:4:9
@@ -15,20 +15,8 @@ LL | #![warn(clashing_extern_declarations)]
1515
= note: expected `unsafe extern "C" fn(u8)`
1616
found `unsafe extern "C" fn(u64)`
1717

18-
warning: `extern_fn` redeclared with a different signature
19-
--> $DIR/clashing-extern-fn.rs:39:9
20-
|
21-
LL | fn extern_fn(x: u64);
22-
| --------------------- `extern_fn` previously declared here
23-
...
24-
LL | fn extern_fn(x: u32);
25-
| ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
26-
|
27-
= note: expected `unsafe extern "C" fn(u64)`
28-
found `unsafe extern "C" fn(u32)`
29-
3018
warning: `extern_link_name` redeclared with a different signature
31-
--> $DIR/clashing-extern-fn.rs:64:9
19+
--> $DIR/clashing-extern-fn.rs:52:9
3220
|
3321
LL | / #[link_name = "extern_link_name"]
3422
LL | | fn some_new_name(x: i16);
@@ -41,7 +29,7 @@ LL | fn extern_link_name(x: u32);
4129
found `unsafe extern "C" fn(u32)`
4230

4331
warning: `some_other_extern_link_name` redeclares `some_other_new_name` with a different signature
44-
--> $DIR/clashing-extern-fn.rs:67:9
32+
--> $DIR/clashing-extern-fn.rs:55:9
4533
|
4634
LL | fn some_other_new_name(x: i16);
4735
| ------------------------------- `some_other_new_name` previously declared here
@@ -55,7 +43,7 @@ LL | | fn some_other_extern_link_name(x: u32);
5543
found `unsafe extern "C" fn(u32)`
5644

5745
warning: `other_both_names_different` redeclares `link_name_same` with a different signature
58-
--> $DIR/clashing-extern-fn.rs:71:9
46+
--> $DIR/clashing-extern-fn.rs:59:9
5947
|
6048
LL | / #[link_name = "link_name_same"]
6149
LL | | fn both_names_different(x: i16);
@@ -70,7 +58,7 @@ LL | | fn other_both_names_different(x: u32);
7058
found `unsafe extern "C" fn(u32)`
7159

7260
warning: `different_mod` redeclared with a different signature
73-
--> $DIR/clashing-extern-fn.rs:84:9
61+
--> $DIR/clashing-extern-fn.rs:72:9
7462
|
7563
LL | fn different_mod(x: u8);
7664
| ------------------------ `different_mod` previously declared here
@@ -82,7 +70,7 @@ LL | fn different_mod(x: u64);
8270
found `unsafe extern "C" fn(u64)`
8371

8472
warning: `variadic_decl` redeclared with a different signature
85-
--> $DIR/clashing-extern-fn.rs:94:9
73+
--> $DIR/clashing-extern-fn.rs:82:9
8674
|
8775
LL | fn variadic_decl(x: u8, ...);
8876
| ----------------------------- `variadic_decl` previously declared here
@@ -94,7 +82,7 @@ LL | fn variadic_decl(x: u8);
9482
found `unsafe extern "C" fn(u8)`
9583

9684
warning: `weigh_banana` redeclared with a different signature
97-
--> $DIR/clashing-extern-fn.rs:154:13
85+
--> $DIR/clashing-extern-fn.rs:142:13
9886
|
9987
LL | fn weigh_banana(count: *const Banana) -> u64;
10088
| --------------------------------------------- `weigh_banana` previously declared here
@@ -106,7 +94,7 @@ LL | fn weigh_banana(count: *const Banana) -> u64;
10694
found `unsafe extern "C" fn(*const banana::three::Banana) -> u64`
10795

10896
warning: `draw_point` redeclared with a different signature
109-
--> $DIR/clashing-extern-fn.rs:183:13
97+
--> $DIR/clashing-extern-fn.rs:171:13
11098
|
11199
LL | fn draw_point(p: Point);
112100
| ------------------------ `draw_point` previously declared here
@@ -117,5 +105,5 @@ LL | fn draw_point(p: Point);
117105
= note: expected `unsafe extern "C" fn(sameish_members::a::Point)`
118106
found `unsafe extern "C" fn(sameish_members::b::Point)`
119107

120-
warning: 9 warnings emitted
108+
warning: 8 warnings emitted
121109

0 commit comments

Comments
 (0)