diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-08-02 06:43:43 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-02 06:43:43 +0200 |
| commit | 67fcb58347c10e0cc047fa3e33108643593ab851 (patch) | |
| tree | da1b3d30502d584567c416ca253bd61f671a0da4 | |
| parent | 2dabaa01aaffd39236e091217937e89c915a7aa3 (diff) | |
| parent | f97aba2271baf1876940b42cc68f1b60ac97bf98 (diff) | |
| download | rust-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.ftl | 3 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/intrinsics.rs | 3 | ||||
| -rw-r--r-- | library/core/src/intrinsics.rs | 6 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/intrinsics/raw_eq_on_ptr.rs | 10 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/intrinsics/raw_eq_on_ptr.stderr | 15 | ||||
| -rw-r--r-- | tests/ui/intrinsics/intrinsic-raw_eq-const-bad.rs | 2 | ||||
| -rw-r--r-- | tests/ui/intrinsics/intrinsic-raw_eq-const-bad.stderr | 5 |
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 |
