Name explicit registers in conflict register errors for inline assembly

This commit is contained in:
George Wort 2023-11-28 10:25:22 +00:00
parent a6b8ae582a
commit e0bfb615da
6 changed files with 43 additions and 22 deletions

View File

@ -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");`.

View File

@ -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,
});
}

View File

@ -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);
}
}

View File

@ -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`
|

View File

@ -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

View File

@ -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