From 2b089147ab0c08afa3275488a318d80f9feb2448 Mon Sep 17 00:00:00 2001
From: Pavel Grigorenko <GrigorenkoPV@ya.ru>
Date: Sat, 6 Jul 2024 19:42:17 +0300
Subject: [PATCH] Add a bunch of tests for #107975

---
 .../codegen/equal-pointers-unequal/README.md  | 22 ++++++
 .../equal-pointers-unequal/as-cast/basic.rs   | 21 ++++++
 .../as-cast/function.rs                       | 22 ++++++
 .../equal-pointers-unequal/as-cast/inline1.rs | 30 ++++++++
 .../equal-pointers-unequal/as-cast/inline2.rs | 30 ++++++++
 .../equal-pointers-unequal/as-cast/print.rs   | 20 ++++++
 .../equal-pointers-unequal/as-cast/print3.rs  | 23 +++++++
 .../as-cast/segfault.rs                       | 63 +++++++++++++++++
 .../equal-pointers-unequal/as-cast/zero.rs    | 28 ++++++++
 .../exposed-provenance/basic.rs               | 25 +++++++
 .../exposed-provenance/function.rs            | 26 +++++++
 .../exposed-provenance/inline1.rs             | 34 ++++++++++
 .../exposed-provenance/inline2.rs             | 34 ++++++++++
 .../exposed-provenance/print.rs               | 24 +++++++
 .../exposed-provenance/print3.rs              | 27 ++++++++
 .../exposed-provenance/segfault.rs            | 68 +++++++++++++++++++
 .../exposed-provenance/zero.rs                | 32 +++++++++
 .../strict-provenance/basic.rs                | 25 +++++++
 .../strict-provenance/function.rs             | 26 +++++++
 .../strict-provenance/inline1.rs              | 34 ++++++++++
 .../strict-provenance/inline2.rs              | 34 ++++++++++
 .../strict-provenance/print.rs                | 24 +++++++
 .../strict-provenance/print3.rs               | 27 ++++++++
 .../strict-provenance/segfault.rs             | 68 +++++++++++++++++++
 .../strict-provenance/zero.rs                 | 32 +++++++++
 25 files changed, 799 insertions(+)
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/README.md
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/segfault.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/zero.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs
 create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs

diff --git a/tests/ui/codegen/equal-pointers-unequal/README.md b/tests/ui/codegen/equal-pointers-unequal/README.md
new file mode 100644
index 0000000000000..343f9646a32cb
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/README.md
@@ -0,0 +1,22 @@
+See https://github.com/rust-lang/rust/issues/107975
+
+Basically, if you have two pointers with the same address but from two different allocations,
+the compiler gets confused whether their addresses are equal or not,
+resulting in some self-contradictory behavior of the compiled code.
+
+This folder contains some examples.
+They all boil down to allocating a variable on the stack, taking its address,
+getting rid of the variable, and then doing it all again.
+This way we end up with two addresses stored in two `usize`s (`a` and `b`).
+The addresses are (probably) equal but (definitely) come from two different allocations.
+Logically, we would expect that exactly one of the following options holds true:
+1. `a == b`
+2. `a != b`
+Sadly, the compiler does not always agree.
+
+Due to Rust having at least three meaningfully different ways
+to get a variable's address as an `usize`,
+each example is provided in three versions, each in the corresponding subfolder:
+1. `./as-cast/` for `&v as *const _ as usize`,
+2. `./strict-provenance/` for `addr_of!(v).addr()`,
+2. `./exposed-provenance/` for `addr_of!(v).expose_provenance()`.
diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs
new file mode 100644
index 0000000000000..e2a00ce173d14
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs
@@ -0,0 +1,21 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+fn main() {
+    let a: usize = {
+        let v = 0u8;
+        &v as *const _ as usize
+    };
+    let b: usize = {
+        let v = 0u8;
+        &v as *const _ as usize
+    };
+
+    // `a` and `b` are not equal.
+    assert_ne!(a, b);
+    // But they are the same number.
+    assert_eq!(format!("{a}"), format!("{b}"));
+    // And they are equal.
+    assert_eq!(a, b);
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs
new file mode 100644
index 0000000000000..15434de50f76c
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs
@@ -0,0 +1,22 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908
+
+fn f() -> usize {
+    let v = 0;
+    &v as *const _ as usize
+}
+
+fn main() {
+    let a = f();
+    let b = f();
+
+    // `a` and `b` are not equal.
+    assert_ne!(a, b);
+    // But they are the same number.
+    assert_eq!(format!("{a}"), format!("{b}"));
+    // And they are equal.
+    assert_eq!(a, b);
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.rs
new file mode 100644
index 0000000000000..d13fd4b63b306
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.rs
@@ -0,0 +1,30 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340
+
+#[inline(never)]
+fn cmp(a: usize, b: usize) -> bool {
+    a == b
+}
+
+#[inline(always)]
+fn cmp_in(a: usize, b: usize) -> bool {
+    a == b
+}
+
+fn main() {
+    let a = {
+        let v = 0;
+        &v as *const _ as usize
+    };
+    let b = {
+        let v = 0;
+        &v as *const _ as usize
+    };
+    assert_eq!(format!("{}", a == b), "false");
+    assert_eq!(format!("{}", cmp_in(a, b)), "false");
+    assert_eq!(format!("{}", cmp(a, b)), "true");
+    assert_eq!(a.to_string(), b.to_string());
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.rs
new file mode 100644
index 0000000000000..9a1ace86e4db8
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.rs
@@ -0,0 +1,30 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340
+
+#[inline(never)]
+fn cmp(a: usize, b: usize) -> bool {
+    a == b
+}
+
+#[inline(always)]
+fn cmp_in(a: usize, b: usize) -> bool {
+    a == b
+}
+
+fn main() {
+    let a = {
+        let v = 0;
+        &v as *const _ as usize
+    };
+    let b = {
+        let v = 0;
+        &v as *const _ as usize
+    };
+    assert_eq!(a.to_string(), b.to_string());
+    assert_eq!(format!("{}", a == b), "true");
+    assert_eq!(format!("{}", cmp_in(a, b)), "true");
+    assert_eq!(format!("{}", cmp(a, b)), "true");
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs
new file mode 100644
index 0000000000000..f33a9e511b61a
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs
@@ -0,0 +1,20 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
+
+fn main() {
+    let a = {
+        let v = 0;
+        &v as *const _ as usize
+    };
+    let b = {
+        let v = 0;
+        &v as *const _ as usize
+    };
+
+    assert_ne!(a, b);
+    println!("{a}"); // or b
+    assert_eq!(a, b);
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs
new file mode 100644
index 0000000000000..eda83e999a528
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs
@@ -0,0 +1,23 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
+
+fn main() {
+    let a = {
+        let v = 0;
+        &v as *const _ as usize
+    };
+    let b = {
+        let v = 0;
+        &v as *const _ as usize
+    };
+
+    assert_ne!(a, b);
+    assert_ne!(a, b);
+    let c = a;
+    assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "false true false");
+    println!("{a} {b}");
+    assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "true true true");
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/segfault.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/segfault.rs
new file mode 100644
index 0000000000000..97a875f15bc89
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/segfault.rs
@@ -0,0 +1,63 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601
+
+use std::cell::{Ref, RefCell};
+
+fn main() {
+    let a: usize = {
+        let v = 0u8;
+        &v as *const _ as usize
+    };
+    let b: usize = {
+        let v = 0u8;
+        &v as *const _ as usize
+    };
+    let i: usize = b - a;
+
+    // A surprise tool that will help us later.
+    let arr = [
+        RefCell::new(Some(Box::new(1u8))),
+        RefCell::new(None),
+        RefCell::new(None),
+        RefCell::new(None),
+    ];
+
+    // `i` is not 0
+    assert_ne!(i, 0);
+
+    // Let's borrow the `i`-th element.
+    // If `i` is out of bounds, indexing will panic.
+    let r: Ref<Option<Box<u8>>> = arr[i].borrow();
+
+    // If we got here, it means `i` was in bounds.
+    // Now, two options are possible:
+    // EITHER `i` is not 0 (as we have asserted above),
+    // so the unwrap will panic, because only the 0-th element is `Some`
+    // OR the assert lied, `i` *is* 0, and the `unwrap` will not panic.
+    let r: &Box<u8> = r.as_ref().unwrap();
+
+    // If we got here, it means `i` *was* actually 0.
+    // Let's ignore the fact that the assert has lied
+    // and try to take a mutable reference to the 0-th element.
+    // `borrow_mut` should panic, because we are sill holding on
+    // to a shared `Ref` for the same `RefCell`.
+    *arr[0].borrow_mut() = None;
+
+    // But it doesn't panic!
+    // We have successfully replaced `Some(Box)` with `None`,
+    // while holding a shared reference to it.
+    // No unsafe involved.
+
+    // The `Box` has been deallocated by now, so this is a dangling reference!
+    let r: &u8 = &*r;
+    println!("{:p}", r);
+
+    // The following might segfault. Or it might not.
+    // Depends on the platform semantics
+    // and whatever happened to the pointed-to memory after deallocation.
+    // let u: u8 = *r;
+    // println!("{u}");
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/zero.rs b/tests/ui/codegen/equal-pointers-unequal/as-cast/zero.rs
new file mode 100644
index 0000000000000..d1aa95a9a569d
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/zero.rs
@@ -0,0 +1,28 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// Derived from https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601
+
+fn main() {
+    let a: usize = {
+        let v = 0u8;
+        &v as *const _ as usize
+    };
+    let b: usize = {
+        let v = 0u8;
+        &v as *const _ as usize
+    };
+
+    // So, are `a` and `b` equal?
+
+    // Let's check their difference.
+    let i: usize = a - b;
+    // It's not zero, which means `a` and `b` are not equal.
+    assert_ne!(i, 0);
+    // But it looks like zero...
+    assert_eq!(i.to_string(), "0");
+    // ...and now it *is* zero?
+    assert_eq!(i, 0);
+    // So `a` and `b` are equal after all?
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs
new file mode 100644
index 0000000000000..0c9df7ecd7827
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs
@@ -0,0 +1,25 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+#![feature(exposed_provenance)]
+
+use std::ptr;
+
+fn main() {
+    let a: usize = {
+        let v = 0u8;
+        ptr::from_ref(&v).expose_provenance()
+    };
+    let b: usize = {
+        let v = 0u8;
+        ptr::from_ref(&v).expose_provenance()
+    };
+
+    // `a` and `b` are not equal.
+    assert_ne!(a, b);
+    // But they are the same number.
+    assert_eq!(format!("{a}"), format!("{b}"));
+    // And they are equal.
+    assert_eq!(a, b);
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs
new file mode 100644
index 0000000000000..b188b794d1fc7
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs
@@ -0,0 +1,26 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908
+
+#![feature(exposed_provenance)]
+
+use std::ptr;
+
+fn f() -> usize {
+    let v = 0;
+    ptr::from_ref(&v).expose_provenance()
+}
+
+fn main() {
+    let a = f();
+    let b = f();
+
+    // `a` and `b` are not equal.
+    assert_ne!(a, b);
+    // But they are the same number.
+    assert_eq!(format!("{a}"), format!("{b}"));
+    // And they are equal.
+    assert_eq!(a, b);
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs
new file mode 100644
index 0000000000000..7f64e23b9c121
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs
@@ -0,0 +1,34 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340
+
+#![feature(exposed_provenance)]
+
+use std::ptr;
+
+#[inline(never)]
+fn cmp(a: usize, b: usize) -> bool {
+    a == b
+}
+
+#[inline(always)]
+fn cmp_in(a: usize, b: usize) -> bool {
+    a == b
+}
+
+fn main() {
+    let a: usize = {
+        let v = 0;
+        ptr::from_ref(&v).expose_provenance()
+    };
+    let b: usize = {
+        let v = 0;
+        ptr::from_ref(&v).expose_provenance()
+    };
+    assert_eq!(format!("{}", a == b), "false");
+    assert_eq!(format!("{}", cmp_in(a, b)), "false");
+    assert_eq!(format!("{}", cmp(a, b)), "true");
+    assert_eq!(a.to_string(), b.to_string());
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs
new file mode 100644
index 0000000000000..3417296ce125a
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs
@@ -0,0 +1,34 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340
+
+#![feature(exposed_provenance)]
+
+use std::ptr;
+
+#[inline(never)]
+fn cmp(a: usize, b: usize) -> bool {
+    a == b
+}
+
+#[inline(always)]
+fn cmp_in(a: usize, b: usize) -> bool {
+    a == b
+}
+
+fn main() {
+    let a: usize = {
+        let v = 0;
+        ptr::from_ref(&v).expose_provenance()
+    };
+    let b: usize = {
+        let v = 0;
+        ptr::from_ref(&v).expose_provenance()
+    };
+    assert_eq!(a.to_string(), b.to_string());
+    assert_eq!(format!("{}", a == b), "true");
+    assert_eq!(format!("{}", cmp_in(a, b)), "true");
+    assert_eq!(format!("{}", cmp(a, b)), "true");
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs
new file mode 100644
index 0000000000000..e1e9e3f46b8ae
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs
@@ -0,0 +1,24 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
+
+#![feature(exposed_provenance)]
+
+use std::ptr;
+
+fn main() {
+    let a: usize = {
+        let v = 0;
+        ptr::from_ref(&v).expose_provenance()
+    };
+    let b: usize = {
+        let v = 0;
+        ptr::from_ref(&v).expose_provenance()
+    };
+
+    assert_ne!(a, b);
+    println!("{a}"); // or b
+    assert_eq!(a, b);
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs
new file mode 100644
index 0000000000000..8d581e8c9e93e
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs
@@ -0,0 +1,27 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
+
+#![feature(exposed_provenance)]
+
+use std::ptr;
+
+fn main() {
+    let a: usize = {
+        let v = 0;
+        ptr::from_ref(&v).expose_provenance()
+    };
+    let b: usize = {
+        let v = 0;
+        ptr::from_ref(&v).expose_provenance()
+    };
+
+    assert_ne!(a, b);
+    assert_ne!(a, b);
+    let c = a;
+    assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "false true false");
+    println!("{a} {b}");
+    assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "true true true");
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs
new file mode 100644
index 0000000000000..506f114cd2a41
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs
@@ -0,0 +1,68 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601
+
+#![feature(exposed_provenance)]
+
+use std::{
+    cell::{Ref, RefCell},
+    ptr,
+};
+
+fn main() {
+    let a: usize = {
+        let v = 0u8;
+        ptr::from_ref(&v).expose_provenance()
+    };
+    let b: usize = {
+        let v = 0u8;
+        ptr::from_ref(&v).expose_provenance()
+    };
+    let i: usize = b - a;
+
+    // A surprise tool that will help us later.
+    let arr = [
+        RefCell::new(Some(Box::new(1u8))),
+        RefCell::new(None),
+        RefCell::new(None),
+        RefCell::new(None),
+    ];
+
+    // `i` is not 0
+    assert_ne!(i, 0);
+
+    // Let's borrow the `i`-th element.
+    // If `i` is out of bounds, indexing will panic.
+    let r: Ref<Option<Box<u8>>> = arr[i].borrow();
+
+    // If we got here, it means `i` was in bounds.
+    // Now, two options are possible:
+    // EITHER `i` is not 0 (as we have asserted above),
+    // so the unwrap will panic, because only the 0-th element is `Some`
+    // OR the assert lied, `i` *is* 0, and the `unwrap` will not panic.
+    let r: &Box<u8> = r.as_ref().unwrap();
+
+    // If we got here, it means `i` *was* actually 0.
+    // Let's ignore the fact that the assert has lied
+    // and try to take a mutable reference to the 0-th element.
+    // `borrow_mut` should panic, because we are sill holding on
+    // to a shared `Ref` for the same `RefCell`.
+    *arr[0].borrow_mut() = None;
+
+    // But it doesn't panic!
+    // We have successfully replaced `Some(Box)` with `None`,
+    // while holding a shared reference to it.
+    // No unsafe involved.
+
+    // The `Box` has been deallocated by now, so this is a dangling reference!
+    let r: &u8 = &*r;
+    println!("{:p}", r);
+
+    // The following might segfault. Or it might not.
+    // Depends on the platform semantics
+    // and whatever happened to the pointed-to memory after deallocation.
+    // let u: u8 = *r;
+    // println!("{u}");
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs
new file mode 100644
index 0000000000000..603db5e08f4af
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs
@@ -0,0 +1,32 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// Derived from https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601
+
+#![feature(exposed_provenance)]
+
+use std::ptr;
+
+fn main() {
+    let a: usize = {
+        let v = 0u8;
+        ptr::from_ref(&v).expose_provenance()
+    };
+    let b: usize = {
+        let v = 0u8;
+        ptr::from_ref(&v).expose_provenance()
+    };
+
+    // So, are `a` and `b` equal?
+
+    // Let's check their difference.
+    let i: usize = a - b;
+    // It's not zero, which means `a` and `b` are not equal.
+    assert_ne!(i, 0);
+    // But it looks like zero...
+    assert_eq!(i.to_string(), "0");
+    // ...and now it *is* zero?
+    assert_eq!(i, 0);
+    // So `a` and `b` are equal after all?
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs
new file mode 100644
index 0000000000000..0243c2bfe9511
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs
@@ -0,0 +1,25 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+#![feature(strict_provenance)]
+
+use std::ptr;
+
+fn main() {
+    let a: usize = {
+        let v = 0u8;
+        ptr::from_ref(&v).addr()
+    };
+    let b: usize = {
+        let v = 0u8;
+        ptr::from_ref(&v).addr()
+    };
+
+    // `a` and `b` are not equal.
+    assert_ne!(a, b);
+    // But they are the same number.
+    assert_eq!(format!("{a}"), format!("{b}"));
+    // And they are equal.
+    assert_eq!(a, b);
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs
new file mode 100644
index 0000000000000..29758036a21ed
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs
@@ -0,0 +1,26 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908
+
+#![feature(strict_provenance)]
+
+use std::ptr;
+
+fn f() -> usize {
+    let v = 0;
+    ptr::from_ref(&v).addr()
+}
+
+fn main() {
+    let a = f();
+    let b = f();
+
+    // `a` and `b` are not equal.
+    assert_ne!(a, b);
+    // But they are the same number.
+    assert_eq!(format!("{a}"), format!("{b}"));
+    // And they are equal.
+    assert_eq!(a, b);
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs
new file mode 100644
index 0000000000000..11925261a6529
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs
@@ -0,0 +1,34 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340
+
+#![feature(strict_provenance)]
+
+use std::ptr;
+
+#[inline(never)]
+fn cmp(a: usize, b: usize) -> bool {
+    a == b
+}
+
+#[inline(always)]
+fn cmp_in(a: usize, b: usize) -> bool {
+    a == b
+}
+
+fn main() {
+    let a: usize = {
+        let v = 0;
+        ptr::from_ref(&v).addr()
+    };
+    let b: usize = {
+        let v = 0;
+        ptr::from_ref(&v).addr()
+    };
+    assert_eq!(format!("{}", a == b), "false");
+    assert_eq!(format!("{}", cmp_in(a, b)), "false");
+    assert_eq!(format!("{}", cmp(a, b)), "true");
+    assert_eq!(a.to_string(), b.to_string());
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs
new file mode 100644
index 0000000000000..e628bb90faac3
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs
@@ -0,0 +1,34 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340
+
+#![feature(strict_provenance)]
+
+use std::ptr;
+
+#[inline(never)]
+fn cmp(a: usize, b: usize) -> bool {
+    a == b
+}
+
+#[inline(always)]
+fn cmp_in(a: usize, b: usize) -> bool {
+    a == b
+}
+
+fn main() {
+    let a: usize = {
+        let v = 0;
+        ptr::from_ref(&v).addr()
+    };
+    let b: usize = {
+        let v = 0;
+        ptr::from_ref(&v).addr()
+    };
+    assert_eq!(a.to_string(), b.to_string());
+    assert_eq!(format!("{}", a == b), "true");
+    assert_eq!(format!("{}", cmp_in(a, b)), "true");
+    assert_eq!(format!("{}", cmp(a, b)), "true");
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs
new file mode 100644
index 0000000000000..075e3475a32cc
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs
@@ -0,0 +1,24 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
+
+#![feature(strict_provenance)]
+
+use std::ptr;
+
+fn main() {
+    let a: usize = {
+        let v = 0;
+        ptr::from_ref(&v).addr()
+    };
+    let b: usize = {
+        let v = 0;
+        ptr::from_ref(&v).addr()
+    };
+
+    assert_ne!(a, b);
+    println!("{a}"); // or b
+    assert_eq!(a, b);
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs
new file mode 100644
index 0000000000000..6d7b6fa33e026
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs
@@ -0,0 +1,27 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499
+
+#![feature(strict_provenance)]
+
+use std::ptr;
+
+fn main() {
+    let a: usize = {
+        let v = 0;
+        ptr::from_ref(&v).addr()
+    };
+    let b: usize = {
+        let v = 0;
+        ptr::from_ref(&v).addr()
+    };
+
+    assert_ne!(a, b);
+    assert_ne!(a, b);
+    let c = a;
+    assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "false true false");
+    println!("{a} {b}");
+    assert_eq!(format!("{} {} {}", a == b, a == c, b == c), "true true true");
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs
new file mode 100644
index 0000000000000..67660d285a48a
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs
@@ -0,0 +1,68 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601
+
+#![feature(strict_provenance)]
+
+use std::{
+    cell::{Ref, RefCell},
+    ptr,
+};
+
+fn main() {
+    let a: usize = {
+        let v = 0u8;
+        ptr::from_ref(&v).addr()
+    };
+    let b: usize = {
+        let v = 0u8;
+        ptr::from_ref(&v).addr()
+    };
+    let i: usize = b - a;
+
+    // A surprise tool that will help us later.
+    let arr = [
+        RefCell::new(Some(Box::new(1u8))),
+        RefCell::new(None),
+        RefCell::new(None),
+        RefCell::new(None),
+    ];
+
+    // `i` is not 0
+    assert_ne!(i, 0);
+
+    // Let's borrow the `i`-th element.
+    // If `i` is out of bounds, indexing will panic.
+    let r: Ref<Option<Box<u8>>> = arr[i].borrow();
+
+    // If we got here, it means `i` was in bounds.
+    // Now, two options are possible:
+    // EITHER `i` is not 0 (as we have asserted above),
+    // so the unwrap will panic, because only the 0-th element is `Some`
+    // OR the assert lied, `i` *is* 0, and the `unwrap` will not panic.
+    let r: &Box<u8> = r.as_ref().unwrap();
+
+    // If we got here, it means `i` *was* actually 0.
+    // Let's ignore the fact that the assert has lied
+    // and try to take a mutable reference to the 0-th element.
+    // `borrow_mut` should panic, because we are sill holding on
+    // to a shared `Ref` for the same `RefCell`.
+    *arr[0].borrow_mut() = None;
+
+    // But it doesn't panic!
+    // We have successfully replaced `Some(Box)` with `None`,
+    // while holding a shared reference to it.
+    // No unsafe involved.
+
+    // The `Box` has been deallocated by now, so this is a dangling reference!
+    let r: &u8 = &*r;
+    println!("{:p}", r);
+
+    // The following might segfault. Or it might not.
+    // Depends on the platform semantics
+    // and whatever happened to the pointed-to memory after deallocation.
+    // let u: u8 = *r;
+    // println!("{u}");
+}
diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs
new file mode 100644
index 0000000000000..a89310f993045
--- /dev/null
+++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs
@@ -0,0 +1,32 @@
+//@ known-bug: #107975
+//@ compile-flags: -Copt-level=2
+//@ run-pass
+
+// Derived from https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601
+
+#![feature(strict_provenance)]
+
+use std::ptr;
+
+fn main() {
+    let a: usize = {
+        let v = 0u8;
+        ptr::from_ref(&v).addr()
+    };
+    let b: usize = {
+        let v = 0u8;
+        ptr::from_ref(&v).addr()
+    };
+
+    // So, are `a` and `b` equal?
+
+    // Let's check their difference.
+    let i: usize = a - b;
+    // It's not zero, which means `a` and `b` are not equal.
+    assert_ne!(i, 0);
+    // But it looks like zero...
+    assert_eq!(i.to_string(), "0");
+    // ...and now it *is* zero?
+    assert_eq!(i, 0);
+    // So `a` and `b` are equal after all?
+}