Skip to content

Confusing diagnostics when the return place and argument overlap in a Call terminator #2851

Closed
@cbeuw

Description

@cbeuw

This program might have UB as the return place and argument operand alias when calling fn2. I'm not sure if there's any conclusion from rust-lang/rust#71117, also the docs only say that the return place cannot alias if arguments are move, but everything's Copy here so maybe this should be fine?

#![feature(custom_mir, core_intrinsics)]
extern crate core;
use core::intrinsics::mir::*;
#[custom_mir(dialect = "runtime", phase = "optimized")]
pub fn fn1(mut x: (i32, bool)) {
    mir! ({
        x.1 = false;
        x.0 = 12;

        Call(x.1, bb1, fn2(x))
    }
    bb1 = {
        Return()
    })
}

pub fn fn2(mut _1: (i32, bool)) -> bool {
    true
}

pub fn main() {
    fn1((1, false));
}

In any case, Miri's error message doesn't really tell you the root cause. If aliasing return place and arguments are to be forbidden, perhaps this should be explicitly checked?

This is with Stacked Borrows:

error: Undefined Behavior: not granting access to tag <3303> because that would remove [Unique for <3304>] which is strongly protected because it is an argument of call 865
  --> repro.rs:10:9
   |
10 |         Call(x.1, bb1, fn2(x))
   |         ^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <3303> because that would remove [Unique for <3304>] which is strongly protected because it is an argument of call 865
   |
   = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
   = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <3303> was created here, as the base tag for alloc1665
  --> repro.rs:7:9
   |
7  |         x.1 = false;
   |         ^^^^^^^^^^^
help: <3304> is this argument
  --> repro.rs:17:1
   |
17 | / pub fn fn2(mut _1: (i32, bool)) -> bool {
18 | |     true
19 | | }
   | |_^
   = note: BACKTRACE (of the first span):
   = note: inside `fn1` at repro.rs:10:9: 10:31
note: inside `main`
  --> repro.rs:21:5
   |
21 |     fn1((1, false));
   |     ^^^^^^^^^^^^^^^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to previous error

This is with -Zmiri-tree-borrows:

error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
  --> repro.rs:10:9
   |
10 |         Call(x.1, bb1, fn2(x))
   |         ^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
   |
   = 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 `fn1` at repro.rs:10:9: 10:31
note: inside `main`
  --> repro.rs:21:5
   |
21 |     fn1((1, false));
   |     ^^^^^^^^^^^^^^^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to previous error

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions