on a signed deref check, mention the right pointer in the error
This commit is contained in:
parent
70591dc15d
commit
de78cb56b2
34 changed files with 192 additions and 141 deletions
|
|
@ -105,15 +105,17 @@ impl<'tcx> EvalContextExtPriv<'tcx> for crate::MiriInterpCx<'tcx> {}
|
|||
trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
// Returns the exposed `AllocId` that corresponds to the specified addr,
|
||||
// or `None` if the addr is out of bounds
|
||||
fn alloc_id_from_addr(&self, addr: u64) -> Option<AllocId> {
|
||||
fn alloc_id_from_addr(&self, addr: u64, size: i64) -> Option<AllocId> {
|
||||
let ecx = self.eval_context_ref();
|
||||
let global_state = ecx.machine.alloc_addresses.borrow();
|
||||
assert!(global_state.provenance_mode != ProvenanceMode::Strict);
|
||||
|
||||
// We always search the allocation to the right of this address. So if the size is structly
|
||||
// negative, we have to search for `addr-1` instead.
|
||||
let addr = if size >= 0 { addr } else { addr.saturating_sub(1) };
|
||||
let pos = global_state.int_to_ptr_map.binary_search_by_key(&addr, |(addr, _)| *addr);
|
||||
|
||||
// Determine the in-bounds provenance for this pointer.
|
||||
// (This is only called on an actual access, so in-bounds is the only possible kind of provenance.)
|
||||
let alloc_id = match pos {
|
||||
Ok(pos) => Some(global_state.int_to_ptr_map[pos].1),
|
||||
Err(0) => None,
|
||||
|
|
@ -318,7 +320,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
/// When a pointer is used for a memory access, this computes where in which allocation the
|
||||
/// access is going.
|
||||
fn ptr_get_alloc(&self, ptr: interpret::Pointer<Provenance>) -> Option<(AllocId, Size)> {
|
||||
fn ptr_get_alloc(
|
||||
&self,
|
||||
ptr: interpret::Pointer<Provenance>,
|
||||
size: i64,
|
||||
) -> Option<(AllocId, Size)> {
|
||||
let ecx = self.eval_context_ref();
|
||||
|
||||
let (tag, addr) = ptr.into_parts(); // addr is absolute (Tag provenance)
|
||||
|
|
@ -327,7 +333,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
alloc_id
|
||||
} else {
|
||||
// A wildcard pointer.
|
||||
ecx.alloc_id_from_addr(addr.bytes())?
|
||||
ecx.alloc_id_from_addr(addr.bytes(), size)?
|
||||
};
|
||||
|
||||
// This cannot fail: since we already have a pointer with that provenance, adjust_alloc_root_pointer
|
||||
|
|
|
|||
|
|
@ -673,7 +673,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// attempt to use it for a non-zero-sized access.
|
||||
// Dangling slices are a common case here; it's valid to get their length but with raw
|
||||
// pointer tagging for example all calls to get_unchecked on them are invalid.
|
||||
if let Ok((alloc_id, base_offset, orig_tag)) = this.ptr_try_get_alloc_id(place.ptr()) {
|
||||
if let Ok((alloc_id, base_offset, orig_tag)) = this.ptr_try_get_alloc_id(place.ptr(), 0) {
|
||||
log_creation(this, Some((alloc_id, base_offset, orig_tag)))?;
|
||||
// Still give it the new provenance, it got retagged after all.
|
||||
return Ok(Some(Provenance::Concrete { alloc_id, tag: new_tag }));
|
||||
|
|
@ -685,7 +685,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
let (alloc_id, base_offset, orig_tag) = this.ptr_get_alloc_id(place.ptr())?;
|
||||
let (alloc_id, base_offset, orig_tag) = this.ptr_get_alloc_id(place.ptr(), 0)?;
|
||||
log_creation(this, Some((alloc_id, base_offset, orig_tag)))?;
|
||||
|
||||
trace!(
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
};
|
||||
|
||||
trace!("Reborrow of size {:?}", ptr_size);
|
||||
let (alloc_id, base_offset, parent_prov) = match this.ptr_try_get_alloc_id(place.ptr()) {
|
||||
let (alloc_id, base_offset, parent_prov) = match this.ptr_try_get_alloc_id(place.ptr(), 0) {
|
||||
Ok(data) => {
|
||||
// Unlike SB, we *do* a proper retag for size 0 if can identify the allocation.
|
||||
// After all, the pointer may be lazily initialized outside this initial range.
|
||||
|
|
|
|||
|
|
@ -1180,7 +1180,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
|||
// We avoid `get_ptr_alloc` since we do *not* want to run the access hooks -- the actual
|
||||
// access will happen later.
|
||||
let (alloc_id, _offset, _prov) = this
|
||||
.ptr_try_get_alloc_id(place.ptr())
|
||||
.ptr_try_get_alloc_id(place.ptr(), 0)
|
||||
.expect("there are no zero-sized atomic accesses");
|
||||
if this.get_alloc_mutability(alloc_id)? == Mutability::Not {
|
||||
// See if this is fine.
|
||||
|
|
@ -1307,7 +1307,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
|||
if let Some(data_race) = &this.machine.data_race {
|
||||
if data_race.race_detecting() {
|
||||
let size = place.layout.size;
|
||||
let (alloc_id, base_offset, _prov) = this.ptr_get_alloc_id(place.ptr())?;
|
||||
let (alloc_id, base_offset, _prov) = this.ptr_get_alloc_id(place.ptr(), 0)?;
|
||||
// Load and log the atomic operation.
|
||||
// Note that atomic loads are possible even from read-only allocations, so `get_alloc_extra_mut` is not an option.
|
||||
let alloc_meta = this.get_alloc_extra(alloc_id)?.data_race.as_ref().unwrap();
|
||||
|
|
|
|||
|
|
@ -468,7 +468,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
init: Scalar,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr())?;
|
||||
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr(), 0)?;
|
||||
if let (
|
||||
crate::AllocExtra { weak_memory: Some(alloc_buffers), .. },
|
||||
crate::MiriMachine { data_race: Some(global), threads, .. },
|
||||
|
|
@ -495,7 +495,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_ref();
|
||||
if let Some(global) = &this.machine.data_race {
|
||||
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr())?;
|
||||
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr(), 0)?;
|
||||
if let Some(alloc_buffers) = this.get_alloc_extra(alloc_id)?.weak_memory.as_ref() {
|
||||
if atomic == AtomicReadOrd::SeqCst {
|
||||
global.sc_read(&this.machine.threads);
|
||||
|
|
@ -535,7 +535,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
init: Scalar,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(dest.ptr())?;
|
||||
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(dest.ptr(), 0)?;
|
||||
if let (
|
||||
crate::AllocExtra { weak_memory: Some(alloc_buffers), .. },
|
||||
crate::MiriMachine { data_race: Some(global), threads, .. },
|
||||
|
|
@ -585,7 +585,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
global.sc_read(&this.machine.threads);
|
||||
}
|
||||
let size = place.layout.size;
|
||||
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr())?;
|
||||
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr(), 0)?;
|
||||
if let Some(alloc_buffers) = this.get_alloc_extra(alloc_id)?.weak_memory.as_ref() {
|
||||
let buffer = alloc_buffers
|
||||
.get_or_create_store_buffer(alloc_range(base_offset, size), init)?;
|
||||
|
|
|
|||
|
|
@ -1198,19 +1198,23 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Convert a pointer with provenance into an allocation-offset pair,
|
||||
/// or a `None` with an absolute address if that conversion is not possible.
|
||||
/// Convert a pointer with provenance into an allocation-offset pair and extra provenance info.
|
||||
/// `size` says how many bytes of memory are expected at that pointer. The *sign* of `size` can
|
||||
/// be used to disambiguate situations where a wildcard pointer sits right in between two
|
||||
/// allocations.
|
||||
///
|
||||
/// This is called when a pointer is about to be used for memory access,
|
||||
/// an in-bounds check, or anything else that requires knowing which allocation it points to.
|
||||
/// If `ptr.provenance.get_alloc_id()` is `Some(p)`, the returned `AllocId` must be `p`.
|
||||
/// The resulting `AllocId` will just be used for that one step and the forgotten again
|
||||
/// (i.e., we'll never turn the data returned here back into a `Pointer` that might be
|
||||
/// stored in machine state).
|
||||
///
|
||||
/// When this fails, that means the pointer does not point to a live allocation.
|
||||
fn ptr_get_alloc(
|
||||
ecx: &MiriInterpCx<'tcx>,
|
||||
ptr: StrictPointer,
|
||||
size: i64,
|
||||
) -> Option<(AllocId, Size, Self::ProvenanceExtra)> {
|
||||
let rel = ecx.ptr_get_alloc(ptr);
|
||||
let rel = ecx.ptr_get_alloc(ptr, size);
|
||||
|
||||
rel.map(|(alloc_id, size)| {
|
||||
let tag = match ptr.provenance {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
// Take apart the pointer, we need its pieces. The offset encodes the span.
|
||||
let (alloc_id, offset, _prov) = this.ptr_get_alloc_id(ptr)?;
|
||||
let (alloc_id, offset, _prov) = this.ptr_get_alloc_id(ptr, 0)?;
|
||||
|
||||
// This has to be an actual global fn ptr, not a dlsym function.
|
||||
let fn_instance = if let Some(GlobalAlloc::Function { instance, .. }) =
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
"miri_get_alloc_id" => {
|
||||
let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr).map_err(|_e| {
|
||||
let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err(|_e| {
|
||||
err_machine_stop!(TerminationInfo::Abort(format!(
|
||||
"pointer passed to `miri_get_alloc_id` must not be dangling, got {ptr:?}"
|
||||
)))
|
||||
|
|
@ -311,7 +311,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
"miri_static_root" => {
|
||||
let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let (alloc_id, offset, _) = this.ptr_get_alloc_id(ptr)?;
|
||||
let (alloc_id, offset, _) = this.ptr_get_alloc_id(ptr, 0)?;
|
||||
if offset != Size::ZERO {
|
||||
throw_unsup_format!(
|
||||
"pointer passed to `miri_static_root` must point to beginning of an allocated block"
|
||||
|
|
@ -392,7 +392,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
"`miri_promise_symbolic_alignment`: pointer is not actually aligned"
|
||||
);
|
||||
}
|
||||
if let Ok((alloc_id, offset, ..)) = this.ptr_try_get_alloc_id(ptr) {
|
||||
if let Ok((alloc_id, offset, ..)) = this.ptr_try_get_alloc_id(ptr, 0) {
|
||||
let (_size, alloc_align, _kind) = this.get_alloc_info(alloc_id);
|
||||
// If the newly promised alignment is bigger than the native alignment of this
|
||||
// allocation, and bigger than the previously promised alignment, then set it.
|
||||
|
|
@ -584,8 +584,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let n = Size::from_bytes(this.read_target_usize(n)?);
|
||||
|
||||
// C requires that this must always be a valid pointer (C18 §7.1.4).
|
||||
this.ptr_get_alloc_id(left)?;
|
||||
this.ptr_get_alloc_id(right)?;
|
||||
this.ptr_get_alloc_id(left, 0)?;
|
||||
this.ptr_get_alloc_id(right, 0)?;
|
||||
|
||||
let result = {
|
||||
let left_bytes = this.read_bytes_ptr_strip_provenance(left, n)?;
|
||||
|
|
@ -612,7 +612,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let val = val as u8;
|
||||
|
||||
// C requires that this must always be a valid pointer (C18 §7.1.4).
|
||||
this.ptr_get_alloc_id(ptr)?;
|
||||
this.ptr_get_alloc_id(ptr, 0)?;
|
||||
|
||||
if let Some(idx) = this
|
||||
.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(num))?
|
||||
|
|
@ -639,7 +639,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let val = val as u8;
|
||||
|
||||
// C requires that this must always be a valid pointer (C18 §7.1.4).
|
||||
this.ptr_get_alloc_id(ptr)?;
|
||||
this.ptr_get_alloc_id(ptr, 0)?;
|
||||
|
||||
let idx = this
|
||||
.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(num))?
|
||||
|
|
@ -681,8 +681,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// C requires that this must always be a valid pointer, even if `n` is zero, so we better check that.
|
||||
// (This is more than Rust requires, so `mem_copy` is not sufficient.)
|
||||
this.ptr_get_alloc_id(ptr_dest)?;
|
||||
this.ptr_get_alloc_id(ptr_src)?;
|
||||
this.ptr_get_alloc_id(ptr_dest, 0)?;
|
||||
this.ptr_get_alloc_id(ptr_src, 0)?;
|
||||
|
||||
this.mem_copy(ptr_src, ptr_dest, Size::from_bytes(n), true)?;
|
||||
this.write_pointer(ptr_dest, dest)?;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: Undefined Behavior: memory access failed: expected a pointer to 129 bytes of memory, but got ALLOC and there are only 128 bytes starting at that pointer
|
||||
error: Undefined Behavior: memory access failed: expected a pointer to 129 bytes of memory, but got ALLOC which is only 128 bytes from the end of the allocation
|
||||
--> $DIR/affinity.rs:LL:CC
|
||||
|
|
||||
LL | let err = unsafe { sched_setaffinity(PID, size_of::<cpu_set_t>() + 1, &cpuset) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 129 bytes of memory, but got ALLOC and there are only 128 bytes starting at that pointer
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 129 bytes of memory, but got ALLOC which is only 128 bytes from the end of the allocation
|
||||
|
|
||||
= 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
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: Undefined Behavior: out-of-bounds pointer use: expected a pointer to 4 bytes of memory, but got ALLOC and there are only 2 bytes starting at that pointer
|
||||
error: Undefined Behavior: out-of-bounds pointer use: expected a pointer to 4 bytes of memory, but got ALLOC which is only 2 bytes from the end of the allocation
|
||||
--> RUSTLIB/alloc/src/boxed.rs:LL:CC
|
||||
|
|
||||
LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: expected a pointer to 4 bytes of memory, but got ALLOC and there are only 2 bytes starting at that pointer
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: expected a pointer to 4 bytes of memory, but got ALLOC which is only 2 bytes from the end of the allocation
|
||||
|
|
||||
= 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
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: Undefined Behavior: out-of-bounds pointer use: expected a pointer to 4 bytes of memory, but got ALLOC and there are only 2 bytes starting at that pointer
|
||||
error: Undefined Behavior: out-of-bounds pointer use: expected a pointer to 4 bytes of memory, but got ALLOC which is only 2 bytes from the end of the allocation
|
||||
--> RUSTLIB/alloc/src/boxed.rs:LL:CC
|
||||
|
|
||||
LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: expected a pointer to 4 bytes of memory, but got ALLOC and there are only 2 bytes starting at that pointer
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: expected a pointer to 4 bytes of memory, but got ALLOC which is only 2 bytes from the end of the allocation
|
||||
|
|
||||
= 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
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: Undefined Behavior: out-of-bounds pointer arithmetic: expected a pointer to 8 bytes of memory, but got ALLOC and there are only 4 bytes starting at that pointer
|
||||
error: Undefined Behavior: out-of-bounds pointer arithmetic: expected a pointer to 8 bytes of memory, but got ALLOC which is only 4 bytes from the end of the allocation
|
||||
--> $DIR/out_of_bounds_project.rs:LL:CC
|
||||
|
|
||||
LL | let _field = addr_of!((*ptr).2);
|
||||
| ^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to 8 bytes of memory, but got ALLOC and there are only 4 bytes starting at that pointer
|
||||
| ^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to 8 bytes of memory, but got ALLOC which is only 4 bytes from the end of the allocation
|
||||
|
|
||||
= 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
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: Undefined Behavior: out-of-bounds pointer arithmetic: expected a pointer to 5 bytes of memory, but got ALLOC and there are only 4 bytes starting at that pointer
|
||||
error: Undefined Behavior: out-of-bounds pointer arithmetic: expected a pointer to 5 bytes of memory, but got ALLOC which is only 4 bytes from the end of the allocation
|
||||
--> $DIR/out_of_bounds_ptr_1.rs:LL:CC
|
||||
|
|
||||
LL | let x = unsafe { x.offset(5) };
|
||||
| ^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to 5 bytes of memory, but got ALLOC and there are only 4 bytes starting at that pointer
|
||||
| ^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to 5 bytes of memory, but got ALLOC which is only 4 bytes from the end of the allocation
|
||||
|
|
||||
= 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
fn main() {
|
||||
let v = [0i8; 4];
|
||||
let x = &v as *const i8;
|
||||
let x = unsafe { x.offset(-1) }; //~ERROR: expected a pointer to 1 byte of memory
|
||||
let x = unsafe { x.offset(-1) }; //~ERROR: expected a pointer to the end of 1 byte of memory
|
||||
panic!("this should never print: {:?}", x);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: Undefined Behavior: out-of-bounds pointer arithmetic: expected a pointer to 1 byte of memory, but got ALLOC-0x1 which points to before the beginning of the allocation
|
||||
error: Undefined Behavior: out-of-bounds pointer arithmetic: expected a pointer to the end of 1 byte of memory, but got ALLOC which is at the beginning of the allocation
|
||||
--> $DIR/out_of_bounds_ptr_3.rs:LL:CC
|
||||
|
|
||||
LL | let x = unsafe { x.offset(-1) };
|
||||
| ^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to 1 byte of memory, but got ALLOC-0x1 which points to before the beginning of the allocation
|
||||
| ^^^^^^^^^^^^ out-of-bounds pointer arithmetic: expected a pointer to the end of 1 byte of memory, but got ALLOC which is at the beginning of the allocation
|
||||
|
|
||||
= 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
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: Undefined Behavior: out-of-bounds `offset_from`: expected a pointer to 1 byte of memory, but got 0xa[noalloc] which is a dangling pointer (it has no provenance)
|
||||
error: Undefined Behavior: out-of-bounds `offset_from` origin: expected a pointer to the end of 1 byte of memory, but got 0xb[noalloc] which is a dangling pointer (it has no provenance)
|
||||
--> $DIR/ptr_offset_from_different_ints.rs:LL:CC
|
||||
|
|
||||
LL | let _ = p1.byte_offset_from(p2);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from`: expected a pointer to 1 byte of memory, but got 0xa[noalloc] which is a dangling pointer (it has no provenance)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from` origin: expected a pointer to the end of 1 byte of memory, but got 0xb[noalloc] which is a dangling pointer (it has no 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue