raw_eq: using it on bytes with provenance is not UB (outside const-eval)

This commit is contained in:
Ralf Jung 2024-07-31 20:26:08 +02:00
parent 99322d84c4
commit f97aba2271
7 changed files with 9 additions and 35 deletions

View file

@ -301,9 +301,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

View file

@ -693,9 +693,6 @@ pub(crate) fn raw_eq_intrinsic(
// 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()
};

View file

@ -2436,11 +2436,13 @@ pub const fn ptr_guaranteed_cmp<T>(ptr: *const T, other: *const T) -> u8 {
///
/// # 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")]

View file

@ -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
}

View file

@ -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

View file

@ -10,7 +10,7 @@
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() {

View file

@ -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