From 3c1ffb92701f7777da295395fa37a4c799b7ab38 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 19 Dec 2024 22:07:05 +0100 Subject: [PATCH 1/2] Report the `unpredictable_function_pointer_comparisons` lint in macro --- compiler/rustc_lint/src/types.rs | 3 +- tests/ui/lint/fn-ptr-comparisons-some.rs | 2 +- tests/ui/lint/fn-ptr-comparisons-some.stderr | 13 ++++- tests/ui/lint/fn-ptr-comparisons-weird.rs | 10 ++++ tests/ui/lint/fn-ptr-comparisons-weird.stderr | 48 ++++++++++++++++--- tests/ui/lint/fn-ptr-comparisons.fixed | 2 - tests/ui/lint/fn-ptr-comparisons.rs | 2 - tests/ui/lint/fn-ptr-comparisons.stderr | 24 +++++----- 8 files changed, 79 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index c0371b1f606d3..ab7163e3e0e3a 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -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)] diff --git a/tests/ui/lint/fn-ptr-comparisons-some.rs b/tests/ui/lint/fn-ptr-comparisons-some.rs index 152e16b9884ba..c6ddd759baa37 100644 --- a/tests/ui/lint/fn-ptr-comparisons-some.rs +++ b/tests/ui/lint/fn-ptr-comparisons-some.rs @@ -12,6 +12,6 @@ fn main() { let _ = Some::(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::(func), Some(func as unsafe extern "C" fn())); + //~^ WARN function pointer comparisons } diff --git a/tests/ui/lint/fn-ptr-comparisons-some.stderr b/tests/ui/lint/fn-ptr-comparisons-some.stderr index eefad05b676de..522c4399bce1d 100644 --- a/tests/ui/lint/fn-ptr-comparisons-some.stderr +++ b/tests/ui/lint/fn-ptr-comparisons-some.stderr @@ -9,5 +9,16 @@ LL | let _ = Some::(func) == Some(func as unsafe extern "C" fn()); = note: for more information visit = 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::(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 + = note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 2 warnings emitted diff --git a/tests/ui/lint/fn-ptr-comparisons-weird.rs b/tests/ui/lint/fn-ptr-comparisons-weird.rs index 171fbfb87279d..c8a8514cafe98 100644 --- a/tests/ui/lint/fn-ptr-comparisons-weird.rs +++ b/tests/ui/lint/fn-ptr-comparisons-weird.rs @@ -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 } diff --git a/tests/ui/lint/fn-ptr-comparisons-weird.stderr b/tests/ui/lint/fn-ptr-comparisons-weird.stderr index f237166392238..b45c098e8fbe2 100644 --- a/tests/ui/lint/fn-ptr-comparisons-weird.stderr +++ b/tests/ui/lint/fn-ptr-comparisons-weird.stderr @@ -1,5 +1,20 @@ 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 + = 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; | ^^^^^ @@ -7,10 +22,9 @@ 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 - = 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 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 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 -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 + = 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 + = note: this warning originates in the macro `assert_ne` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: 7 warnings emitted diff --git a/tests/ui/lint/fn-ptr-comparisons.fixed b/tests/ui/lint/fn-ptr-comparisons.fixed index 22f16177a0446..41cdb7bf6aea0 100644 --- a/tests/ui/lint/fn-ptr-comparisons.fixed +++ b/tests/ui/lint/fn-ptr-comparisons.fixed @@ -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 } diff --git a/tests/ui/lint/fn-ptr-comparisons.rs b/tests/ui/lint/fn-ptr-comparisons.rs index 90a8ab5c926b6..c2601d6adfba4 100644 --- a/tests/ui/lint/fn-ptr-comparisons.rs +++ b/tests/ui/lint/fn-ptr-comparisons.rs @@ -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 } diff --git a/tests/ui/lint/fn-ptr-comparisons.stderr b/tests/ui/lint/fn-ptr-comparisons.stderr index eaba23a461ab6..53c742f8d775c 100644 --- a/tests/ui/lint/fn-ptr-comparisons.stderr +++ b/tests/ui/lint/fn-ptr-comparisons.stderr @@ -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; | ^^^^^^^^^^^^ From 8f0693363342f35614ac97ba99ce7f3db89bb11f Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 19 Dec 2024 22:33:49 +0100 Subject: [PATCH 2/2] Allow `unpredictable_function_pointer_comparisons` lint in more places --- library/core/src/task/wake.rs | 1 + tests/ui/issues/issue-28561.rs | 1 + tests/ui/mir/mir_refs_correct.rs | 2 ++ tests/ui/nullable-pointer-iotareduction.rs | 2 ++ 4 files changed, 6 insertions(+) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index ba429005fab3d..5787fb2ca7082 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -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 diff --git a/tests/ui/issues/issue-28561.rs b/tests/ui/issues/issue-28561.rs index f9b0ceb22fc66..642b2193a4f9b 100644 --- a/tests/ui/issues/issue-28561.rs +++ b/tests/ui/issues/issue-28561.rs @@ -37,6 +37,7 @@ struct Array { } #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[allow(unpredictable_function_pointer_comparisons)] struct Fn { f00: fn(), f01: fn(A), diff --git a/tests/ui/mir/mir_refs_correct.rs b/tests/ui/mir/mir_refs_correct.rs index fc23c8c3631eb..f1832d90a0f56 100644 --- a/tests/ui/mir/mir_refs_correct.rs +++ b/tests/ui/mir/mir_refs_correct.rs @@ -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); diff --git a/tests/ui/nullable-pointer-iotareduction.rs b/tests/ui/nullable-pointer-iotareduction.rs index fa837dab51b6c..1b73164c9fc74 100644 --- a/tests/ui/nullable-pointer-iotareduction.rs +++ b/tests/ui/nullable-pointer-iotareduction.rs @@ -8,6 +8,8 @@ // trying to get assert failure messages that at least identify which case // failed. +#![allow(unpredictable_function_pointer_comparisons)] + enum E { Thing(isize, T), #[allow(dead_code)] Nothing((), ((), ()), [i8; 0]) } impl E { fn is_none(&self) -> bool {