From a7c36d19549abc3e8bced326cf56a05b95953d53 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko 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 | 20 ++++++++++ .../as-cast/function.rs | 21 +++++++++++ .../equal-pointers-unequal/as-cast/inline1.rs | 29 +++++++++++++++ .../as-cast/inline1.run.stdout | 1 + .../equal-pointers-unequal/as-cast/inline2.rs | 29 +++++++++++++++ .../as-cast/inline2.run.stdout | 1 + .../equal-pointers-unequal/as-cast/print.rs | 21 +++++++++++ .../as-cast/print.run.stdout | 3 ++ .../equal-pointers-unequal/as-cast/print3.rs | 24 ++++++++++++ .../as-cast/print3.run.stdout | 5 +++ .../as-cast/segfault.rs | 35 ++++++++++++++++++ .../equal-pointers-unequal/as-cast/zero.rs | 27 ++++++++++++++ .../exposed-provenance/basic.rs | 24 ++++++++++++ .../exposed-provenance/function.rs | 25 +++++++++++++ .../exposed-provenance/inline1.rs | 34 +++++++++++++++++ .../exposed-provenance/inline1.run.stdout | 1 + .../exposed-provenance/inline2.rs | 33 +++++++++++++++++ .../exposed-provenance/inline2.run.stdout | 1 + .../exposed-provenance/print.rs | 25 +++++++++++++ .../exposed-provenance/print.run.stdout | 3 ++ .../exposed-provenance/print3.rs | 28 ++++++++++++++ .../exposed-provenance/print3.run.stdout | 5 +++ .../exposed-provenance/segfault.rs | 37 +++++++++++++++++++ .../exposed-provenance/zero.rs | 31 ++++++++++++++++ .../strict-provenance/basic.rs | 24 ++++++++++++ .../strict-provenance/function.rs | 25 +++++++++++++ .../strict-provenance/inline1.rs | 34 +++++++++++++++++ .../strict-provenance/inline1.run.stdout | 1 + .../strict-provenance/inline2.rs | 33 +++++++++++++++++ .../strict-provenance/inline2.run.stdout | 1 + .../strict-provenance/print.rs | 25 +++++++++++++ .../strict-provenance/print.run.stdout | 3 ++ .../strict-provenance/print3.rs | 28 ++++++++++++++ .../strict-provenance/print3.run.stdout | 5 +++ .../strict-provenance/segfault.rs | 37 +++++++++++++++++++ .../strict-provenance/zero.rs | 31 ++++++++++++++++ 37 files changed, 732 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/inline1.run.stdout create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.rs create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.run.stdout create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/print.run.stdout create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs create mode 100644 tests/ui/codegen/equal-pointers-unequal/as-cast/print3.run.stdout 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/inline1.run.stdout create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.run.stdout create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.run.stdout create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs create mode 100644 tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.run.stdout 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/inline1.run.stdout create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.run.stdout create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.run.stdout create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs create mode 100644 tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.run.stdout 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..cd4712f5eb70f --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/basic.rs @@ -0,0 +1,20 @@ +//@ known-bug: #107975 +//@ 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..fcdd14e442dc3 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/function.rs @@ -0,0 +1,21 @@ +//@ known-bug: #107975 +//@ 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..6da2d486f736b --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.rs @@ -0,0 +1,29 @@ +//@ known-bug: #107975 +//@ run-pass +//@ check-run-results +//@ normalize-stdout-test: "\d+" -> "<..>" + +// 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 + }; + println!("{a:?} == {b:?} -> ==: {}, cmp_in: {}, cmp: {}", a == b, cmp_in(a, b), cmp(a, b)); + assert_eq!(a.to_string(), b.to_string()); +} diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.run.stdout b/tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.run.stdout new file mode 100644 index 0000000000000..bf061737348e5 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/inline1.run.stdout @@ -0,0 +1 @@ +<..> == <..> -> ==: false, cmp_in: false, cmp: true 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..9a6feb82bef2b --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.rs @@ -0,0 +1,29 @@ +//@ known-bug: #107975 +//@ run-pass +//@ check-run-results +//@ normalize-stdout-test: "\d+" -> "<..>" + +// 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()); + println!("{a:?} == {b:?} -> ==: {}, cmp_in: {}, cmp: {}", a == b, cmp_in(a, b), cmp(a, b)); +} diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.run.stdout b/tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.run.stdout new file mode 100644 index 0000000000000..581a9c6efd61d --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/inline2.run.stdout @@ -0,0 +1 @@ +<..> == <..> -> ==: true, cmp_in: true, cmp: 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..25a4899c0643e --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/print.rs @@ -0,0 +1,21 @@ +//@ known-bug: #107975 +//@ run-pass +//@ check-run-results +//@ normalize-stdout-test: "\d+" -> "<..>" + +// 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 + }; + + println!("{}", a == b); // prints false + println!("{a}"); // or b + println!("{}", a == b); // prints true +} diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/print.run.stdout b/tests/ui/codegen/equal-pointers-unequal/as-cast/print.run.stdout new file mode 100644 index 0000000000000..e9997f6521e95 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/print.run.stdout @@ -0,0 +1,3 @@ +false +<..> +true 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..331fedba6521c --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/print3.rs @@ -0,0 +1,24 @@ +//@ known-bug: #107975 +//@ run-pass +//@ check-run-results +//@ normalize-stdout-test: "\d+" -> "<..>" + +// 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 + }; + + println!("{}", a == b); // false + println!("{}", a == b); // false + let c = a; + println!("{} {} {}", a == b, a == c, b == c); // false true false + println!("{a} {b}"); + println!("{} {} {}", a == b, a == c, b == c); // true true true +} diff --git a/tests/ui/codegen/equal-pointers-unequal/as-cast/print3.run.stdout b/tests/ui/codegen/equal-pointers-unequal/as-cast/print3.run.stdout new file mode 100644 index 0000000000000..03b7976944f4b --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/print3.run.stdout @@ -0,0 +1,5 @@ +false +false +false true false +<..> <..> +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..edbacb1ba4beb --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/segfault.rs @@ -0,0 +1,35 @@ +//@ known-bug: #107975 +//@ run-fail +//@ check-run-results +//@ compile-flags: -Copt-level=3 + +// This one should segfault. +// I don't know a better way to check for segfault other than +// check that it fails and that the output is empty. + +// https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601 + +use std::cell::RefCell; + +fn main() { + let a = { + let v = 0u8; + &v as *const _ as usize + }; + let b = { + let v = 0u8; + &v as *const _ as usize + }; + let i = b - a; + let arr = [ + RefCell::new(Some(Box::new(1))), + RefCell::new(None), + RefCell::new(None), + RefCell::new(None), + ]; + assert_ne!(i, 0); + let r = arr[i].borrow(); + let r = r.as_ref().unwrap(); + *arr[0].borrow_mut() = None; + println!("{}", *r); +} 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..8d67f8b0434d6 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/as-cast/zero.rs @@ -0,0 +1,27 @@ +//@ known-bug: #107975 +//@ 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..b06bff13d90f5 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/basic.rs @@ -0,0 +1,24 @@ +//@ known-bug: #107975 +//@ run-pass + +#![feature(exposed_provenance)] + +use std::ptr::addr_of; + +fn main() { + let a: usize = { + let v = 0u8; + addr_of!(v).expose_provenance() + }; + let b: usize = { + let v = 0u8; + addr_of!(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..34b6eaed62247 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/function.rs @@ -0,0 +1,25 @@ +//@ known-bug: #107975 +//@ run-pass + +// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908 + +#![feature(exposed_provenance)] + +use std::ptr::addr_of; + +fn f() -> usize { + let v = 0; + addr_of!(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..d04ec8d34604e --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.rs @@ -0,0 +1,34 @@ +//@ known-bug: #107975 +//@ run-pass +//@ check-run-results +//@ normalize-stdout-test: "\d+" -> "<..>" + +// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340 + + +#![feature(exposed_provenance)] + +use std::ptr::addr_of; + +#[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; + addr_of!(v).expose_provenance() + }; + let b = { + let v = 0; + addr_of!(v).expose_provenance() + }; + println!("{a:?} == {b:?} -> ==: {}, cmp_in: {}, cmp: {}", a == b, cmp_in(a, b), cmp(a, b)); + assert_eq!(a.to_string(), b.to_string()); +} diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.run.stdout b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.run.stdout new file mode 100644 index 0000000000000..bf061737348e5 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline1.run.stdout @@ -0,0 +1 @@ +<..> == <..> -> ==: false, cmp_in: false, cmp: true 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..f99ac8f7ffbe8 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.rs @@ -0,0 +1,33 @@ +//@ known-bug: #107975 +//@ run-pass +//@ check-run-results +//@ normalize-stdout-test: "\d+" -> "<..>" + +// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340 + +#![feature(exposed_provenance)] + +use std::ptr::addr_of; + +#[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; + addr_of!(v).expose_provenance() + }; + let b = { + let v = 0; + addr_of!(v).expose_provenance() + }; + assert_eq!(a.to_string(), b.to_string()); + println!("{a:?} == {b:?} -> ==: {}, cmp_in: {}, cmp: {}", a == b, cmp_in(a, b), cmp(a, b)); +} diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.run.stdout b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.run.stdout new file mode 100644 index 0000000000000..581a9c6efd61d --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/inline2.run.stdout @@ -0,0 +1 @@ +<..> == <..> -> ==: true, cmp_in: true, cmp: 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..56ba18243b292 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.rs @@ -0,0 +1,25 @@ +//@ known-bug: #107975 +//@ run-pass +//@ check-run-results +//@ normalize-stdout-test: "\d+" -> "<..>" + +// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499 + +#![feature(exposed_provenance)] + +use std::ptr::addr_of; + +fn main() { + let a = { + let v = 0; + addr_of!(v).expose_provenance() + }; + let b = { + let v = 0; + addr_of!(v).expose_provenance() + }; + + println!("{}", a == b); // prints false + println!("{a}"); // or b + println!("{}", a == b); // prints true +} diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.run.stdout b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.run.stdout new file mode 100644 index 0000000000000..e9997f6521e95 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print.run.stdout @@ -0,0 +1,3 @@ +false +<..> +true 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..0554fc86b0393 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.rs @@ -0,0 +1,28 @@ +//@ known-bug: #107975 +//@ run-pass +//@ check-run-results +//@ normalize-stdout-test: "\d+" -> "<..>" + +// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499 + +#![feature(exposed_provenance)] + +use std::ptr::addr_of; + +fn main() { + let a = { + let v = 0; + addr_of!(v).expose_provenance() + }; + let b = { + let v = 0; + addr_of!(v).expose_provenance() + }; + + println!("{}", a == b); // false + println!("{}", a == b); // false + let c = a; + println!("{} {} {}", a == b, a == c, b == c); // false true false + println!("{a} {b}"); + println!("{} {} {}", a == b, a == c, b == c); // true true true +} diff --git a/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.run.stdout b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.run.stdout new file mode 100644 index 0000000000000..03b7976944f4b --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/print3.run.stdout @@ -0,0 +1,5 @@ +false +false +false true false +<..> <..> +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..7c602660e4269 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/segfault.rs @@ -0,0 +1,37 @@ +//@ known-bug: #107975 +//@ run-fail +//@ check-run-results +//@ compile-flags: -Copt-level=3 + +// This one should segfault. +// I don't know a better way to check for segfault other than +// check that it fails and that the output is empty. + +// https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601 + +#![feature(exposed_provenance)] + +use std::{cell::RefCell, ptr::addr_of}; + +fn main() { + let a = { + let v = 0u8; + addr_of!(v).expose_provenance() + }; + let b = { + let v = 0u8; + addr_of!(v).expose_provenance() + }; + let i = b - a; + let arr = [ + RefCell::new(Some(Box::new(1))), + RefCell::new(None), + RefCell::new(None), + RefCell::new(None), + ]; + assert_ne!(i, 0); + let r = arr[i].borrow(); + let r = r.as_ref().unwrap(); + *arr[0].borrow_mut() = None; + println!("{}", *r); +} 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..719180b4f5070 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/exposed-provenance/zero.rs @@ -0,0 +1,31 @@ +//@ known-bug: #107975 +//@ run-pass + +// Derived from https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601 + +#![feature(exposed_provenance)] + +use std::ptr::addr_of; + +fn main() { + let a: usize = { + let v = 0u8; + addr_of!(v).expose_provenance() + }; + let b: usize = { + let v = 0u8; + addr_of!(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..9a05381954eac --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/basic.rs @@ -0,0 +1,24 @@ +//@ known-bug: #107975 +//@ run-pass + +#![feature(strict_provenance)] + +use std::ptr::addr_of; + +fn main() { + let a: usize = { + let v = 0u8; + addr_of!(v).addr() + }; + let b: usize = { + let v = 0u8; + addr_of!(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..0e14ee72b974f --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/function.rs @@ -0,0 +1,25 @@ +//@ known-bug: #107975 +//@ run-pass + +// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1434203908 + +#![feature(strict_provenance)] + +use std::ptr::addr_of; + +fn f() -> usize { + let v = 0; + addr_of!(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..b88e1ddb61874 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.rs @@ -0,0 +1,34 @@ +//@ known-bug: #107975 +//@ run-pass +//@ check-run-results +//@ normalize-stdout-test: "\d+" -> "<..>" + +// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340 + + +#![feature(strict_provenance)] + +use std::ptr::addr_of; + +#[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; + addr_of!(v).addr() + }; + let b = { + let v = 0; + addr_of!(v).addr() + }; + println!("{a:?} == {b:?} -> ==: {}, cmp_in: {}, cmp: {}", a == b, cmp_in(a, b), cmp(a, b)); + assert_eq!(a.to_string(), b.to_string()); +} diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.run.stdout b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.run.stdout new file mode 100644 index 0000000000000..bf061737348e5 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline1.run.stdout @@ -0,0 +1 @@ +<..> == <..> -> ==: false, cmp_in: false, cmp: true 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..abfc1ada6345c --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.rs @@ -0,0 +1,33 @@ +//@ known-bug: #107975 +//@ run-pass +//@ check-run-results +//@ normalize-stdout-test: "\d+" -> "<..>" + +// Based on https://github.com/rust-lang/rust/issues/107975#issuecomment-1432161340 + +#![feature(strict_provenance)] + +use std::ptr::addr_of; + +#[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; + addr_of!(v).addr() + }; + let b = { + let v = 0; + addr_of!(v).addr() + }; + assert_eq!(a.to_string(), b.to_string()); + println!("{a:?} == {b:?} -> ==: {}, cmp_in: {}, cmp: {}", a == b, cmp_in(a, b), cmp(a, b)); +} diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.run.stdout b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.run.stdout new file mode 100644 index 0000000000000..581a9c6efd61d --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/inline2.run.stdout @@ -0,0 +1 @@ +<..> == <..> -> ==: true, cmp_in: true, cmp: 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..1eeaed65cbf32 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.rs @@ -0,0 +1,25 @@ +//@ known-bug: #107975 +//@ run-pass +//@ check-run-results +//@ normalize-stdout-test: "\d+" -> "<..>" + +// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499 + +#![feature(strict_provenance)] + +use std::ptr::addr_of; + +fn main() { + let a = { + let v = 0; + addr_of!(v).addr() + }; + let b = { + let v = 0; + addr_of!(v).addr() + }; + + println!("{}", a == b); // prints false + println!("{a}"); // or b + println!("{}", a == b); // prints true +} diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.run.stdout b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.run.stdout new file mode 100644 index 0000000000000..e9997f6521e95 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print.run.stdout @@ -0,0 +1,3 @@ +false +<..> +true 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..d64ce913dba1c --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.rs @@ -0,0 +1,28 @@ +//@ known-bug: #107975 +//@ run-pass +//@ check-run-results +//@ normalize-stdout-test: "\d+" -> "<..>" + +// https://github.com/rust-lang/rust/issues/107975#issuecomment-1430704499 + +#![feature(strict_provenance)] + +use std::ptr::addr_of; + +fn main() { + let a = { + let v = 0; + addr_of!(v).addr() + }; + let b = { + let v = 0; + addr_of!(v).addr() + }; + + println!("{}", a == b); // false + println!("{}", a == b); // false + let c = a; + println!("{} {} {}", a == b, a == c, b == c); // false true false + println!("{a} {b}"); + println!("{} {} {}", a == b, a == c, b == c); // true true true +} diff --git a/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.run.stdout b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.run.stdout new file mode 100644 index 0000000000000..03b7976944f4b --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/print3.run.stdout @@ -0,0 +1,5 @@ +false +false +false true false +<..> <..> +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..15bf3df4d45ee --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/segfault.rs @@ -0,0 +1,37 @@ +//@ known-bug: #107975 +//@ run-fail +//@ check-run-results +//@ compile-flags: -Copt-level=3 + +// This one should segfault. +// I don't know a better way to check for segfault other than +// check that it fails and that the output is empty. + +// https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601 + +#![feature(strict_provenance)] + +use std::{cell::RefCell, ptr::addr_of}; + +fn main() { + let a = { + let v = 0u8; + addr_of!(v).addr() + }; + let b = { + let v = 0u8; + addr_of!(v).addr() + }; + let i = b - a; + let arr = [ + RefCell::new(Some(Box::new(1))), + RefCell::new(None), + RefCell::new(None), + RefCell::new(None), + ]; + assert_ne!(i, 0); + let r = arr[i].borrow(); + let r = r.as_ref().unwrap(); + *arr[0].borrow_mut() = None; + println!("{}", *r); +} 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..1f7f5ade43389 --- /dev/null +++ b/tests/ui/codegen/equal-pointers-unequal/strict-provenance/zero.rs @@ -0,0 +1,31 @@ +//@ known-bug: #107975 +//@ run-pass + +// Derived from https://github.com/rust-lang/rust/issues/107975#issuecomment-1431758601 + +#![feature(strict_provenance)] + +use std::ptr::addr_of; + +fn main() { + let a: usize = { + let v = 0u8; + addr_of!(v).addr() + }; + let b: usize = { + let v = 0u8; + addr_of!(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? +}