mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
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`
This commit is contained in:
commit
67fcb58347
@ -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
|
||||
|
@ -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()
|
||||
};
|
||||
|
||||
|
@ -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")]
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user