Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lint on fn pointers comparisons in external macros #134536

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
@@ -193,7 +193,8 @@ declare_lint! {
/// same address after being merged together.
UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS,
Warn,
"detects unpredictable function pointer comparisons"
"detects unpredictable function pointer comparisons",
report_in_external_macro
}

#[derive(Copy, Clone, Default)]
1 change: 1 addition & 0 deletions library/core/src/task/wake.rs
Original file line number Diff line number Diff line change
@@ -107,6 +107,7 @@ impl RawWaker {
/// synchronization. This is because [`LocalWaker`] is not thread safe itself, so it cannot
/// be sent across threads.
#[stable(feature = "futures_api", since = "1.36.0")]
#[cfg_attr(not(bootstrap), allow(unpredictable_function_pointer_comparisons))]
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct RawWakerVTable {
/// This function will be called when the [`RawWaker`] gets cloned, e.g. when
1 change: 1 addition & 0 deletions tests/ui/issues/issue-28561.rs
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@ struct Array<T> {
}

#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[allow(unpredictable_function_pointer_comparisons)]
struct Fn<A, B, C, D, E, F, G, H, I, J, K, L> {
f00: fn(),
f01: fn(A),
2 changes: 1 addition & 1 deletion tests/ui/lint/fn-ptr-comparisons-some.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,6 @@ fn main() {
let _ = Some::<FnPtr>(func) == Some(func as unsafe extern "C" fn());
//~^ WARN function pointer comparisons

// Undecided as of https://github.com/rust-lang/rust/pull/134536
assert_eq!(Some::<FnPtr>(func), Some(func as unsafe extern "C" fn()));
//~^ WARN function pointer comparisons
}
13 changes: 12 additions & 1 deletion tests/ui/lint/fn-ptr-comparisons-some.stderr
Original file line number Diff line number Diff line change
@@ -9,5 +9,16 @@ LL | let _ = Some::<FnPtr>(func) == Some(func as unsafe extern "C" fn());
= note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html>
= note: `#[warn(unpredictable_function_pointer_comparisons)]` on by default

warning: 1 warning emitted
warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons-some.rs:15:5
|
LL | assert_eq!(Some::<FnPtr>(func), Some(func as unsafe extern "C" fn()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the address of the same function can vary between different codegen units
= note: furthermore, different functions could have the same address after being merged together
= note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html>
= note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: 2 warnings emitted

10 changes: 10 additions & 0 deletions tests/ui/lint/fn-ptr-comparisons-weird.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
//@ check-pass

#[derive(PartialEq, Eq)]
struct A {
f: fn(),
//~^ WARN function pointer comparisons
}

fn main() {
let f: fn() = main;
let g: fn() = main;
@@ -12,4 +18,8 @@ fn main() {
//~^ WARN function pointer comparisons
let _ = f < g;
//~^ WARN function pointer comparisons
let _ = assert_eq!(g, g);
//~^ WARN function pointer comparisons
let _ = assert_ne!(g, g);
//~^ WARN function pointer comparisons
}
48 changes: 42 additions & 6 deletions tests/ui/lint/fn-ptr-comparisons-weird.stderr
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons-weird.rs:7:13
--> $DIR/fn-ptr-comparisons-weird.rs:5:5
|
LL | #[derive(PartialEq, Eq)]
| --------- in this derive macro expansion
LL | struct A {
LL | f: fn(),
| ^^^^^^^
|
= note: the address of the same function can vary between different codegen units
= note: furthermore, different functions could have the same address after being merged together
= note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html>
= note: `#[warn(unpredictable_function_pointer_comparisons)]` on by default
= note: this warning originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons-weird.rs:13:13
|
LL | let _ = f > g;
| ^^^^^
|
= note: the address of the same function can vary between different codegen units
= note: furthermore, different functions could have the same address after being merged together
= note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html>
= note: `#[warn(unpredictable_function_pointer_comparisons)]` on by default

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons-weird.rs:9:13
--> $DIR/fn-ptr-comparisons-weird.rs:15:13
|
LL | let _ = f >= g;
| ^^^^^^
@@ -20,7 +34,7 @@ LL | let _ = f >= g;
= note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html>

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons-weird.rs:11:13
--> $DIR/fn-ptr-comparisons-weird.rs:17:13
|
LL | let _ = f <= g;
| ^^^^^^
@@ -30,7 +44,7 @@ LL | let _ = f <= g;
= note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html>

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons-weird.rs:13:13
--> $DIR/fn-ptr-comparisons-weird.rs:19:13
|
LL | let _ = f < g;
| ^^^^^
@@ -39,5 +53,27 @@ LL | let _ = f < g;
= note: furthermore, different functions could have the same address after being merged together
= note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html>

warning: 4 warnings emitted
warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons-weird.rs:21:13
|
LL | let _ = assert_eq!(g, g);
| ^^^^^^^^^^^^^^^^
|
= note: the address of the same function can vary between different codegen units
= note: furthermore, different functions could have the same address after being merged together
= note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html>
= note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons-weird.rs:23:13
|
LL | let _ = assert_ne!(g, g);
| ^^^^^^^^^^^^^^^^
|
= note: the address of the same function can vary between different codegen units
= note: furthermore, different functions could have the same address after being merged together
= note: for more information visit <https://doc.rust-lang.org/nightly/core/ptr/fn.fn_addr_eq.html>
= note: this warning originates in the macro `assert_ne` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: 7 warnings emitted

2 changes: 0 additions & 2 deletions tests/ui/lint/fn-ptr-comparisons.fixed
Original file line number Diff line number Diff line change
@@ -11,7 +11,6 @@ extern "C" fn c() {}

extern "C" fn args(_a: i32) -> i32 { 0 }

#[derive(PartialEq, Eq)]
struct A {
f: fn(),
}
@@ -52,7 +51,6 @@ fn main() {
let _ = std::ptr::fn_addr_eq(t, test as unsafe extern "C" fn());
//~^ WARN function pointer comparisons

let _ = a1 == a2; // should not warn
let _ = std::ptr::fn_addr_eq(a1.f, a2.f);
//~^ WARN function pointer comparisons
}
2 changes: 0 additions & 2 deletions tests/ui/lint/fn-ptr-comparisons.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,6 @@ extern "C" fn c() {}

extern "C" fn args(_a: i32) -> i32 { 0 }

#[derive(PartialEq, Eq)]
struct A {
f: fn(),
}
@@ -52,7 +51,6 @@ fn main() {
let _ = t == test;
//~^ WARN function pointer comparisons

let _ = a1 == a2; // should not warn
let _ = a1.f == a2.f;
//~^ WARN function pointer comparisons
}
24 changes: 12 additions & 12 deletions tests/ui/lint/fn-ptr-comparisons.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons.rs:26:13
--> $DIR/fn-ptr-comparisons.rs:25:13
|
LL | let _ = f == a;
| ^^^^^^
@@ -14,7 +14,7 @@ LL | let _ = std::ptr::fn_addr_eq(f, a as fn());
| +++++++++++++++++++++ ~ ++++++++

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons.rs:28:13
--> $DIR/fn-ptr-comparisons.rs:27:13
|
LL | let _ = f != a;
| ^^^^^^
@@ -28,7 +28,7 @@ LL | let _ = !std::ptr::fn_addr_eq(f, a as fn());
| ++++++++++++++++++++++ ~ ++++++++

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons.rs:30:13
--> $DIR/fn-ptr-comparisons.rs:29:13
|
LL | let _ = f == g;
| ^^^^^^
@@ -42,7 +42,7 @@ LL | let _ = std::ptr::fn_addr_eq(f, g);
| +++++++++++++++++++++ ~ +

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons.rs:32:13
--> $DIR/fn-ptr-comparisons.rs:31:13
|
LL | let _ = f == f;
| ^^^^^^
@@ -56,7 +56,7 @@ LL | let _ = std::ptr::fn_addr_eq(f, f);
| +++++++++++++++++++++ ~ +

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons.rs:34:13
--> $DIR/fn-ptr-comparisons.rs:33:13
|
LL | let _ = g == g;
| ^^^^^^
@@ -70,7 +70,7 @@ LL | let _ = std::ptr::fn_addr_eq(g, g);
| +++++++++++++++++++++ ~ +

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons.rs:36:13
--> $DIR/fn-ptr-comparisons.rs:35:13
|
LL | let _ = g == g;
| ^^^^^^
@@ -84,7 +84,7 @@ LL | let _ = std::ptr::fn_addr_eq(g, g);
| +++++++++++++++++++++ ~ +

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons.rs:38:13
--> $DIR/fn-ptr-comparisons.rs:37:13
|
LL | let _ = &g == &g;
| ^^^^^^^^
@@ -98,7 +98,7 @@ LL | let _ = std::ptr::fn_addr_eq(g, g);
| ~~~~~~~~~~~~~~~~~~~~~ ~ +

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons.rs:40:13
--> $DIR/fn-ptr-comparisons.rs:39:13
|
LL | let _ = a as fn() == g;
| ^^^^^^^^^^^^^^
@@ -112,7 +112,7 @@ LL | let _ = std::ptr::fn_addr_eq(a as fn(), g);
| +++++++++++++++++++++ ~ +

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons.rs:44:13
--> $DIR/fn-ptr-comparisons.rs:43:13
|
LL | let _ = cfn == c;
| ^^^^^^^^
@@ -126,7 +126,7 @@ LL | let _ = std::ptr::fn_addr_eq(cfn, c as extern "C" fn());
| +++++++++++++++++++++ ~ +++++++++++++++++++

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons.rs:48:13
--> $DIR/fn-ptr-comparisons.rs:47:13
|
LL | let _ = argsfn == args;
| ^^^^^^^^^^^^^^
@@ -140,7 +140,7 @@ LL | let _ = std::ptr::fn_addr_eq(argsfn, args as extern "C" fn(i32) -> i32)
| +++++++++++++++++++++ ~ +++++++++++++++++++++++++++++

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons.rs:52:13
--> $DIR/fn-ptr-comparisons.rs:51:13
|
LL | let _ = t == test;
| ^^^^^^^^^
@@ -154,7 +154,7 @@ LL | let _ = std::ptr::fn_addr_eq(t, test as unsafe extern "C" fn());
| +++++++++++++++++++++ ~ ++++++++++++++++++++++++++

warning: function pointer comparisons do not produce meaningful results since their addresses are not guaranteed to be unique
--> $DIR/fn-ptr-comparisons.rs:56:13
--> $DIR/fn-ptr-comparisons.rs:54:13
|
LL | let _ = a1.f == a2.f;
| ^^^^^^^^^^^^
2 changes: 2 additions & 0 deletions tests/ui/mir/mir_refs_correct.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//@ run-pass
//@ aux-build:mir_external_refs.rs

#![allow(unpredictable_function_pointer_comparisons)]

extern crate mir_external_refs as ext;

struct S(#[allow(dead_code)] u8);
2 changes: 2 additions & 0 deletions tests/ui/nullable-pointer-iotareduction.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,8 @@
// trying to get assert failure messages that at least identify which case
// failed.

#![allow(unpredictable_function_pointer_comparisons)]

enum E<T> { Thing(isize, T), #[allow(dead_code)] Nothing((), ((), ()), [i8; 0]) }
impl<T> E<T> {
fn is_none(&self) -> bool {
Loading