Skip to content

Commit 06e3a1d

Browse files
authored
Rollup merge of #72607 - Amanieu:fix-72570, r=oli-obk
Eagerly lower asm sub-expressions to HIR even if there is an error Fixes #72570 r? @oli-obk
2 parents aabcb25 + de53276 commit 06e3a1d

File tree

3 files changed

+54
-34
lines changed

3 files changed

+54
-34
lines changed

src/librustc_ast_lowering/expr.rs

+36-34
Original file line numberDiff line numberDiff line change
@@ -974,20 +974,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
974974
}
975975

976976
fn lower_expr_asm(&mut self, sp: Span, asm: &InlineAsm) -> hir::ExprKind<'hir> {
977-
let asm_arch = if let Some(asm_arch) = self.sess.asm_arch {
978-
asm_arch
979-
} else {
977+
if self.sess.asm_arch.is_none() {
980978
struct_span_err!(self.sess, sp, E0472, "asm! is unsupported on this target").emit();
981-
return hir::ExprKind::Err;
982-
};
983-
if asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
984-
match asm_arch {
985-
asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64 => {}
986-
_ => self
987-
.sess
988-
.struct_span_err(sp, "the `att_syntax` option is only supported on x86")
989-
.emit(),
990-
}
979+
}
980+
if asm.options.contains(InlineAsmOptions::ATT_SYNTAX)
981+
&& !matches!(
982+
self.sess.asm_arch,
983+
Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64)
984+
)
985+
{
986+
self.sess
987+
.struct_span_err(sp, "the `att_syntax` option is only supported on x86")
988+
.emit();
991989
}
992990

993991
// Lower operands to HIR, filter_map skips any operands with invalid
@@ -1001,10 +999,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
1001999
Some(match reg {
10021000
InlineAsmRegOrRegClass::Reg(s) => asm::InlineAsmRegOrRegClass::Reg(
10031001
asm::InlineAsmReg::parse(
1004-
asm_arch,
1005-
|feature| {
1006-
self.sess.target_features.contains(&Symbol::intern(feature))
1007-
},
1002+
sess.asm_arch?,
1003+
|feature| sess.target_features.contains(&Symbol::intern(feature)),
10081004
s,
10091005
)
10101006
.map_err(|e| {
@@ -1015,7 +1011,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10151011
),
10161012
InlineAsmRegOrRegClass::RegClass(s) => {
10171013
asm::InlineAsmRegOrRegClass::RegClass(
1018-
asm::InlineAsmRegClass::parse(asm_arch, s)
1014+
asm::InlineAsmRegClass::parse(sess.asm_arch?, s)
10191015
.map_err(|e| {
10201016
let msg = format!(
10211017
"invalid register class `{}`: {}",
@@ -1029,33 +1025,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
10291025
}
10301026
})
10311027
};
1032-
let op = match op {
1033-
InlineAsmOperand::In { reg, expr } => hir::InlineAsmOperand::In {
1034-
reg: lower_reg(*reg)?,
1028+
1029+
// lower_reg is executed last because we need to lower all
1030+
// sub-expressions even if we throw them away later.
1031+
let op = match *op {
1032+
InlineAsmOperand::In { reg, ref expr } => hir::InlineAsmOperand::In {
10351033
expr: self.lower_expr_mut(expr),
1034+
reg: lower_reg(reg)?,
10361035
},
1037-
InlineAsmOperand::Out { reg, late, expr } => hir::InlineAsmOperand::Out {
1038-
reg: lower_reg(*reg)?,
1039-
late: *late,
1036+
InlineAsmOperand::Out { reg, late, ref expr } => hir::InlineAsmOperand::Out {
1037+
late,
10401038
expr: expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
1039+
reg: lower_reg(reg)?,
10411040
},
1042-
InlineAsmOperand::InOut { reg, late, expr } => hir::InlineAsmOperand::InOut {
1043-
reg: lower_reg(*reg)?,
1044-
late: *late,
1045-
expr: self.lower_expr_mut(expr),
1046-
},
1047-
InlineAsmOperand::SplitInOut { reg, late, in_expr, out_expr } => {
1041+
InlineAsmOperand::InOut { reg, late, ref expr } => {
1042+
hir::InlineAsmOperand::InOut {
1043+
late,
1044+
expr: self.lower_expr_mut(expr),
1045+
reg: lower_reg(reg)?,
1046+
}
1047+
}
1048+
InlineAsmOperand::SplitInOut { reg, late, ref in_expr, ref out_expr } => {
10481049
hir::InlineAsmOperand::SplitInOut {
1049-
reg: lower_reg(*reg)?,
1050-
late: *late,
1050+
late,
10511051
in_expr: self.lower_expr_mut(in_expr),
10521052
out_expr: out_expr.as_ref().map(|expr| self.lower_expr_mut(expr)),
1053+
reg: lower_reg(reg)?,
10531054
}
10541055
}
1055-
InlineAsmOperand::Const { expr } => {
1056+
InlineAsmOperand::Const { ref expr } => {
10561057
hir::InlineAsmOperand::Const { expr: self.lower_expr_mut(expr) }
10571058
}
1058-
InlineAsmOperand::Sym { expr } => {
1059+
InlineAsmOperand::Sym { ref expr } => {
10591060
hir::InlineAsmOperand::Sym { expr: self.lower_expr_mut(expr) }
10601061
}
10611062
};
@@ -1069,6 +1070,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10691070
}
10701071

10711072
// Validate template modifiers against the register classes for the operands
1073+
let asm_arch = sess.asm_arch.unwrap();
10721074
for p in &asm.template {
10731075
if let InlineAsmTemplatePiece::Placeholder {
10741076
operand_idx,

src/test/ui/asm/issue-72570.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// only-x86_64
2+
3+
#![feature(asm)]
4+
5+
fn main() {
6+
unsafe {
7+
asm!("", in("invalid") "".len());
8+
//~^ ERROR: invalid register `invalid`: unknown register
9+
}
10+
}

src/test/ui/asm/issue-72570.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: invalid register `invalid`: unknown register
2+
--> $DIR/issue-72570.rs:7:18
3+
|
4+
LL | asm!("", in("invalid") "".len());
5+
| ^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)