about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-08-02 06:43:43 +0200
committerGitHub <noreply@github.com>2024-08-02 06:43:43 +0200
commit67fcb58347c10e0cc047fa3e33108643593ab851 (patch)
treeda1b3d30502d584567c416ca253bd61f671a0da4
parent2dabaa01aaffd39236e091217937e89c915a7aa3 (diff)
parentf97aba2271baf1876940b42cc68f1b60ac97bf98 (diff)
downloadrust-67fcb58347c10e0cc047fa3e33108643593ab851.tar.gz
rust-67fcb58347c10e0cc047fa3e33108643593ab851.zip
Rollup merge of #128453 - RalfJung:raw_eq, r=saethlin
raw_eq: using it on bytes with provenance is not UB (outside const-eval)

The current behavior of raw_eq violates provenance monotonicity. See https://github.com/rust-lang/rust/pull/124921 for an explanation of provenance monotonicity. It is violated in raw_eq because comparing bytes without provenance is well-defined, but adding provenance makes the operation UB.

So remove the no-provenance requirement from raw_eq. However, the requirement stays in-place for compile-time invocations of raw_eq, that indeed cannot deal with provenance.

Cc `@rust-lang/opsem`
-rw-r--r--compiler/rustc_const_eval/messages.ftl3
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs3
-rw-r--r--library/core/src/intrinsics.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/raw_eq_on_ptr.rs10
-rw-r--r--src/tools/miri/tests/fail/intrinsics/raw_eq_on_ptr.stderr15
-rw-r--r--tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs2
-rw-r--r--tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr5
7 files changed, 9 insertions, 35 deletions
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 94cdd021d8d..c64c73b2323 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -316,9 +316,6 @@ const_eval_range_upper = less or equal to {$hi}
 const_eval_range_wrapping = less or equal to {$hi}, or greater or equal to {$lo}
 const_eval_raw_bytes = the raw bytes of the constant (size: {$size}, align: {$align}) {"{"}{$bytes}{"}"}
 
-const_eval_raw_eq_with_provenance =
-    `raw_eq` on bytes with provenance
-
 const_eval_raw_ptr_comparison =
     pointers cannot be reliably compared during const eval
     .note = see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 3cf3bd87d3d..16a0a76a316 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -690,9 +690,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 // zero-sized access
                 return Ok(&[]);
             };
-            if alloc_ref.has_provenance() {
-                throw_ub_custom!(fluent::const_eval_raw_eq_with_provenance);
-            }
             alloc_ref.get_bytes_strip_provenance()
         };
 
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 13c7f0855d8..e9eacbcd25a 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2436,11 +2436,13 @@ extern "rust-intrinsic" {
     ///
     /// # Safety
     ///
-    /// It's UB to call this if any of the *bytes* in `*a` or `*b` are uninitialized or carry a
-    /// pointer value.
+    /// It's UB to call this if any of the *bytes* in `*a` or `*b` are uninitialized.
     /// Note that this is a stricter criterion than just the *values* being
     /// fully-initialized: if `T` has padding, it's UB to call this intrinsic.
     ///
+    /// At compile-time, it is furthermore UB to call this if any of the bytes
+    /// in `*a` or `*b` have provenance.
+    ///
     /// (The implementation is allowed to branch on the results of comparisons,
     /// which is UB if any of their inputs are `undef`.)
     #[rustc_const_unstable(feature = "const_intrinsic_raw_eq", issue = "none")]
diff --git a/src/tools/miri/tests/fail/intrinsics/raw_eq_on_ptr.rs b/src/tools/miri/tests/fail/intrinsics/raw_eq_on_ptr.rs
deleted file mode 100644
index c14f86147db..00000000000
--- a/src/tools/miri/tests/fail/intrinsics/raw_eq_on_ptr.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-#![feature(intrinsics)]
-
-extern "rust-intrinsic" {
-    fn raw_eq<T>(a: &T, b: &T) -> bool;
-}
-
-fn main() {
-    let x = &0;
-    unsafe { raw_eq(&x, &x) }; //~ERROR: `raw_eq` on bytes with provenance
-}
diff --git a/src/tools/miri/tests/fail/intrinsics/raw_eq_on_ptr.stderr b/src/tools/miri/tests/fail/intrinsics/raw_eq_on_ptr.stderr
deleted file mode 100644
index 83f81fa726e..00000000000
--- a/src/tools/miri/tests/fail/intrinsics/raw_eq_on_ptr.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error: Undefined Behavior: `raw_eq` on bytes with provenance
-  --> $DIR/raw_eq_on_ptr.rs:LL:CC
-   |
-LL |     unsafe { raw_eq(&x, &x) };
-   |              ^^^^^^^^^^^^^^ `raw_eq` on bytes with provenance
-   |
-   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
-   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
-   = note: BACKTRACE:
-   = note: inside `main` at $DIR/raw_eq_on_ptr.rs:LL:CC
-
-note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs
index 0e894ef581c..ab46fd796c5 100644
--- a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs
+++ b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs
@@ -10,7 +10,7 @@ const RAW_EQ_PADDING: bool = unsafe {
 const RAW_EQ_PTR: bool = unsafe {
     std::intrinsics::raw_eq(&(&0), &(&1))
 //~^ ERROR evaluation of constant value failed
-//~| `raw_eq` on bytes with provenance
+//~| unable to turn pointer into integer
 };
 
 pub fn main() {
diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr
index 317466eb322..af16c2bc64a 100644
--- a/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr
+++ b/tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr
@@ -8,7 +8,10 @@ error[E0080]: evaluation of constant value failed
   --> $DIR/intrinsic-raw_eq-const-bad.rs:11:5
    |
 LL |     std::intrinsics::raw_eq(&(&0), &(&1))
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `raw_eq` on bytes with provenance
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into integer
+   |
+   = help: this code performed an operation that depends on the underlying bytes representing a pointer
+   = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
 
 error: aborting due to 2 previous errors