Skip to content

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

@arielb1

Description

@arielb1
Contributor

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)

Activity

added
I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
on Nov 1, 2017
changed the title [-]MIR: asm statements don't participate in data movement[/-] [+]MIR: asm statements don't participate in moveck[/+] on Nov 1, 2017
nikomatsakis

nikomatsakis commented on Nov 10, 2017

@nikomatsakis
Contributor

@arielb1

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)

To be clear, you are saying this is a pre-existing bug with drop elaboration?

added this to the NLL prototype milestone on Nov 15, 2017
nikomatsakis

nikomatsakis commented on Nov 16, 2017

@nikomatsakis
Contributor

Removing from demo milestone, though this seems like a good one to mentor as an intro to how things work.

removed this from the NLL prototype milestone on Nov 16, 2017
arielb1

arielb1 commented on Nov 19, 2017

@arielb1
ContributorAuthor

This should be fairly easy to fix, but @matthewjasper is refactoring the area a bit in #46022, so I would wait for him to be done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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

        Participants

        @nikomatsakis@arielb1

        Issue actions

          MIR: asm statements don't participate in moveck · Issue #45695 · rust-lang/rust