mirror of https://github.com/rust-lang/rust.git
Name explicit registers in conflict register errors for inline assembly
This commit is contained in:
parent
a6b8ae582a
commit
e0bfb615da
|
@ -2237,6 +2237,18 @@ pub enum InlineAsmOperand {
|
|||
},
|
||||
}
|
||||
|
||||
impl InlineAsmOperand {
|
||||
pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
|
||||
match self {
|
||||
Self::In { reg, .. }
|
||||
| Self::Out { reg, .. }
|
||||
| Self::InOut { reg, .. }
|
||||
| Self::SplitInOut { reg, .. } => Some(reg),
|
||||
Self::Const { .. } | Self::Sym { .. } => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Inline assembly.
|
||||
///
|
||||
/// E.g., `asm!("NOP");`.
|
||||
|
|
|
@ -353,10 +353,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
let idx2 = *o.get();
|
||||
let (ref op2, op_sp2) = operands[idx2];
|
||||
let Some(asm::InlineAsmRegOrRegClass::Reg(reg2)) = op2.reg()
|
||||
else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
let in_out = match (op, op2) {
|
||||
(
|
||||
|
@ -374,11 +370,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
_ => None,
|
||||
};
|
||||
|
||||
let reg_str = |idx| -> &str {
|
||||
// HIR asm doesn't preserve the original alias string of the explicit register,
|
||||
// so we have to retrieve it from AST
|
||||
let (op, _): &(InlineAsmOperand, Span) = &asm.operands[idx];
|
||||
if let Some(ast::InlineAsmRegOrRegClass::Reg(reg_sym)) =
|
||||
op.reg()
|
||||
{
|
||||
reg_sym.as_str()
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
};
|
||||
|
||||
sess.emit_err(RegisterConflict {
|
||||
op_span1: op_sp,
|
||||
op_span2: op_sp2,
|
||||
reg1_name: reg.name(),
|
||||
reg2_name: reg2.name(),
|
||||
reg1_name: reg_str(idx),
|
||||
reg2_name: reg_str(idx2),
|
||||
in_out,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -48,14 +48,14 @@ fn main() {
|
|||
// (except in/lateout which don't conflict)
|
||||
|
||||
asm!("", in("x0") foo, in("w0") bar);
|
||||
//~^ ERROR register `x0` conflicts with register `x0`
|
||||
//~^ ERROR register `w0` conflicts with register `x0`
|
||||
asm!("", in("x0") foo, out("x0") bar);
|
||||
//~^ ERROR register `x0` conflicts with register `x0`
|
||||
asm!("", in("w0") foo, lateout("w0") bar);
|
||||
asm!("", in("v0") foo, in("q0") bar);
|
||||
//~^ ERROR register `v0` conflicts with register `v0`
|
||||
//~^ ERROR register `q0` conflicts with register `v0`
|
||||
asm!("", in("v0") foo, out("q0") bar);
|
||||
//~^ ERROR register `v0` conflicts with register `v0`
|
||||
//~^ ERROR register `q0` conflicts with register `v0`
|
||||
asm!("", in("v0") foo, lateout("q0") bar);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,11 +98,11 @@ error: register class `preg` can only be used as a clobber, not as an input or o
|
|||
LL | asm!("{}", out(preg) _);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: register `x0` conflicts with register `x0`
|
||||
error: register `w0` conflicts with register `x0`
|
||||
--> $DIR/bad-reg.rs:50:32
|
||||
|
|
||||
LL | asm!("", in("x0") foo, in("w0") bar);
|
||||
| ------------ ^^^^^^^^^^^^ register `x0`
|
||||
| ------------ ^^^^^^^^^^^^ register `w0`
|
||||
| |
|
||||
| register `x0`
|
||||
|
||||
|
@ -120,19 +120,19 @@ help: use `lateout` instead of `out` to avoid conflict
|
|||
LL | asm!("", in("x0") foo, out("x0") bar);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: register `v0` conflicts with register `v0`
|
||||
error: register `q0` conflicts with register `v0`
|
||||
--> $DIR/bad-reg.rs:55:32
|
||||
|
|
||||
LL | asm!("", in("v0") foo, in("q0") bar);
|
||||
| ------------ ^^^^^^^^^^^^ register `v0`
|
||||
| ------------ ^^^^^^^^^^^^ register `q0`
|
||||
| |
|
||||
| register `v0`
|
||||
|
||||
error: register `v0` conflicts with register `v0`
|
||||
error: register `q0` conflicts with register `v0`
|
||||
--> $DIR/bad-reg.rs:57:32
|
||||
|
|
||||
LL | asm!("", in("v0") foo, out("q0") bar);
|
||||
| ------------ ^^^^^^^^^^^^^ register `v0`
|
||||
| ------------ ^^^^^^^^^^^^^ register `q0`
|
||||
| |
|
||||
| register `v0`
|
||||
|
|
||||
|
|
|
@ -56,10 +56,10 @@ fn main() {
|
|||
// (except in/lateout which don't conflict)
|
||||
|
||||
asm!("", in("eax") foo, in("al") bar);
|
||||
//~^ ERROR register `al` conflicts with register `ax`
|
||||
//~^ ERROR register `al` conflicts with register `eax`
|
||||
//~| ERROR `i32` cannot be used with this register class
|
||||
asm!("", in("rax") foo, out("rax") bar);
|
||||
//~^ ERROR register `ax` conflicts with register `ax`
|
||||
//~^ ERROR register `rax` conflicts with register `rax`
|
||||
asm!("", in("al") foo, lateout("al") bar);
|
||||
//~^ ERROR `i32` cannot be used with this register class
|
||||
//~| ERROR `i32` cannot be used with this register class
|
||||
|
|
|
@ -106,21 +106,21 @@ error: register class `mmx_reg` can only be used as a clobber, not as an input o
|
|||
LL | asm!("{}", out(mmx_reg) _);
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: register `al` conflicts with register `ax`
|
||||
error: register `al` conflicts with register `eax`
|
||||
--> $DIR/bad-reg.rs:58:33
|
||||
|
|
||||
LL | asm!("", in("eax") foo, in("al") bar);
|
||||
| ------------- ^^^^^^^^^^^^ register `al`
|
||||
| |
|
||||
| register `ax`
|
||||
| register `eax`
|
||||
|
||||
error: register `ax` conflicts with register `ax`
|
||||
error: register `rax` conflicts with register `rax`
|
||||
--> $DIR/bad-reg.rs:61:33
|
||||
|
|
||||
LL | asm!("", in("rax") foo, out("rax") bar);
|
||||
| ------------- ^^^^^^^^^^^^^^ register `ax`
|
||||
| ------------- ^^^^^^^^^^^^^^ register `rax`
|
||||
| |
|
||||
| register `ax`
|
||||
| register `rax`
|
||||
|
|
||||
help: use `lateout` instead of `out` to avoid conflict
|
||||
--> $DIR/bad-reg.rs:61:18
|
||||
|
|
Loading…
Reference in New Issue