Skip to content

MIR: asm statements don't participate in moveck #45695

Closed
@arielb1

Description

@arielb1

For example,

#![feature(asm)]

fn main() {
    let y: &mut isize;
    let x = &mut 0isize;
    unsafe {
        asm!("mov $1, $0" : "=r"(y) : "r"(x));
    }
    println!("{} {}", x, y);
}

This errors out in this way (with MIR borrowck enabled):

error[E0382]: use of moved value: `x` (Ast)
 --> fail.rs:9:23
  |
7 |         asm!("mov $1, $0" : "=r"(y) : "r"(x));
  |                                           - value moved here
8 |     }
9 |     println!("{} {}", x, y);
  |                       ^ value used here after move
  |
  = note: move occurs because `x` has type `&mut isize`, which does not implement the `Copy` trait

error[E0381]: borrow of possibly uninitialized variable: `x` (Mir)
 --> fail.rs:9:23
  |
9 |     println!("{} {}", x, y);
  |                       ^ use of possibly uninitialized `x`

error[E0381]: borrow of possibly uninitialized variable: `y` (Mir)
 --> fail.rs:9:26
  |
9 |     println!("{} {}", x, y);
  |                          ^ use of possibly uninitialized `y`

error: aborting due to 3 previous errors

Where only x is uninitialized with the AST borrowck, but both are uninitialized with MIR borrowck

Also, if there's a destructor for an input, it will run right after the asm statement is executed, which doesn't make any sense (the assertion there should fail, not succeed)

#![feature(asm)]

use std::cell::Cell;

#[repr(C)]
struct NoisyDrop<'a>(&'a Cell<&'static str>);
impl<'a> Drop for NoisyDrop<'a> {
    fn drop(&mut self) {
        self.0.set("destroyed!");
    }
}

fn main() {
    let status = Cell::new("alive");
    let _y: Box<NoisyDrop>;
    let x = Box::new(NoisyDrop(&status));
    unsafe {
        asm!("mov $1, $0" : "=r"(_y) : "r"(x));
    }
    assert_eq!(status.get(), "destroyed!"); // this makes 0 sense
}

This is because move checking just ignores inline asm, while it should treat them like AST borrowck does (inputs move data out, outputs move data in)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-borrow-checkerArea: The borrow checkerA-inline-assemblyArea: Inline assembly (`asm!(…)`)I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions