Skip to content

Confusing Miri error when byte_offset_from is used on two different invalid pointers. #3104

@asquared31415

Description

@asquared31415

The following code causes Miri to emit an error that I think does not properly describe the issue.

#![feature(strict_provenance)]
#![feature(pointer_byte_offsets)]
use core::ptr;

fn main() {
    unsafe {
        let base = ptr::without_provenance::<()>(10);
        let unit = &*base;
        let p1 = unit as *const ();

        let base = ptr::without_provenance::<()>(11);
        let unit = &*base;
        let p2 = unit as *const ();

        // Seems to work because they are same pointer
        // even though it's dangling.
        let _ = p1.byte_offset_from(p1);

        // UB because different allocations, but reports
        // the error being that p1 is dangling.
        let _ = p1.byte_offset_from(p2);
    }
}
error: Undefined Behavior: out-of-bounds `offset_from`: 0xa[noalloc] is a dangling pointer (it has no provenance)
  --> src/main.rs:21:17
   |
21 |         let _ = p1.byte_offset_from(p2);
   |                 ^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds `offset_from`: 0xa[noalloc] 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
   = note: BACKTRACE:
   = note: inside `main` at src/main.rs:21:17: 21:40

It is confusing that Miri seems to complain about the pointer being dangling, since it does not complain when a dangling pointer is offset from itself. I believe the true issue is that they are not pointers to the same object, but the fact that they're not really pointers to objects at all makes the error less useful. Additionally, Miri is seemingly fine with the code if both of the pointers are invalid with the same integer and emits error: Undefined Behavior: `ptr_offset_from` called on pointers into different allocations if only one pointer is invalid and the other is a pointer to an object (including freed).

I believe that this error should be the normal "offset_from called on pointers to different allocations" error. (perhaps with an additional note saying that the inputs are both invalid?)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticserrors and warnings emitted by miriC-enhancementCategory: a PR with an enhancement or an issue tracking an accepted enhancement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions