Description
... and it is unclear whether this is intended (inbounds only cares about the allocated object bounds) or a bug (inbounds should respect subobject provenance).
Both the starting and resulting pointer must be either in bounds or one byte past the end of the same allocated object.
Allocated object
For several operations, such as
offset
or field projections (expr.field
), the notion of an “allocated object” becomes relevant. An allocated object is a contiguous region of memory. Common examples of allocated objects include stack-allocated variables (each variable is a separate allocated object), heap allocations (each allocation created by the global allocator is a separate allocated object), andstatic
variables.
and ptr::read
says
src
must be valid for reads.
Pointer validity
The precise rules for validity are not determined yet. The guarantees that are provided at this point are very minimal:
- For a pointer to be valid, it is necessary, but not always sufficient, that the pointer be dereferenceable: the memory range of the given size starting at the pointer must all be within the bounds of a single allocated object.
- The result of casting a reference to a pointer is valid for as long as the underlying object is live and no reference (just raw pointers) is used to access the same memory.
Stronger guarantees will be provided eventually, as the aliasing rules are being determined. For more information, see the book as well as the section in the reference devoted to undefined behavior.
Example:
#![feature(raw_ref_op)]
#[allow(unused_must_use, clippy::no_effect)]
fn main() { unsafe {
// alloc id 2200, tag 4409
let place = [0u8; 5];
// tag 4410 at alloc2200[0x0..0x1]
let p = &raw const place[0];
let q = p.offset(4); // not diagnosed ub
// attempting a read access using <4410> at alloc2200[0x4]
*q; // ub
} }
Tracking:
note: tracking was triggered (x5)
--> src\main.rs:7:21
|
7 | let place = [0u8; 5];
| ^^^^^^^^ created stack variable allocation of 5 bytes (alignment 1 bytes) with id 2200
| ^^^^^^^^ created tag 4409
|
10 | let p = &raw const place[0];
| ^^^^^^^^^^^^^^^^^^^ created tag 4410 at alloc2200[0x0..0x1]
|
= note: inside `main` at src\main.rs
error: Undefined Behavior: attempting a read access using <4410> at alloc2200[0x4], but that tag does not exist in the borrow stack for this location
--> src\main.rs:17:9
|
17 | *q; // ub
| ^^
| |
| attempting a read access using <4410> at alloc2200[0x4], but that tag does not exist in the borrow stack for this location
| this error occurs as part of an access at alloc2200[0x4..0x5]
|
help: <4410> was created by a retag at offsets [0x0..0x1]
--> src\main.rs:10:17
|
10 | let p = &raw const place[0];
| ^^^^^^^^^^^^^^^^^^^
= note: inside `main` at src\main.rs
trace
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] New allocation alloc2200 has base tag <4409>
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] write access with tag <4409>: alloc2200, size 1
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] read access with tag <4409>: alloc2200, size 1
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] read access with tag <4409>: alloc2200, size 1
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] write access with tag <4409>: alloc2200+0x1, size 4
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] reborrow: raw (constant) reference <4410> derived from <4409> (pointee u8): alloc2200, size 1
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] reborrow: adding item [SharedReadOnly for <4410>]
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] new_call: Assigning ID 1330
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] New allocation alloc2201 has base tag <4411>
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] reborrow: unique reference <4412> derived from <4411> (pointee *const u8): alloc2201, size 8
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] reborrow: adding item [Unique for <4412> (call 1330)]
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] write access with tag <4412>: alloc2201, size 8
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] read access with tag <4412>: alloc2201, size 8
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] read access with tag <4411>: alloc2201, size 8
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] access: disabling item [Unique for <4412> (call 1330)]
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] read access with tag <4410>: alloc2200+0x4, size 1
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] read access with tag <1>: alloc1, size 8
[2022-07-10T18:42:10Z TRACE miri::stacked_borrows] deallocation with tag <2>: alloc2, size 8
error: Undefined Behavior: attempting a read access using <4410> at alloc2200[0x4], but that tag does not exist in the borrow stack for this location