Skip to content

Commit

Permalink
Rollup merge of rust-lang#87985 - nbdd0121:asm, r=Amanieu
Browse files Browse the repository at this point in the history
Forbid `!` from being used in `asm!` output

Fixes rust-lang#87802

r? ```@Amanieu```
  • Loading branch information
camsteffen committed Aug 15, 2021
2 parents 8756a24 + 6ec1b53 commit 1164f48
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
15 changes: 10 additions & 5 deletions compiler/rustc_passes/src/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ impl ExprVisitor<'tcx> {
reg: InlineAsmRegOrRegClass,
expr: &hir::Expr<'tcx>,
template: &[InlineAsmTemplatePiece],
is_input: bool,
tied_input: Option<(&hir::Expr<'tcx>, Option<InlineAsmType>)>,
) -> Option<InlineAsmType> {
// Check the type against the allowed types for inline asm.
Expand All @@ -150,7 +151,9 @@ impl ExprVisitor<'tcx> {
_ => unreachable!(),
};
let asm_ty = match *ty.kind() {
ty::Never | ty::Error(_) => return None,
// `!` is allowed for input but not for output (issue #87802)
ty::Never if is_input => return None,
ty::Error(_) => return None,
ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::I8),
ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => Some(InlineAsmType::I16),
ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => Some(InlineAsmType::I32),
Expand Down Expand Up @@ -350,24 +353,26 @@ impl ExprVisitor<'tcx> {
for (idx, (op, _)) in asm.operands.iter().enumerate() {
match *op {
hir::InlineAsmOperand::In { reg, ref expr } => {
self.check_asm_operand_type(idx, reg, expr, asm.template, None);
self.check_asm_operand_type(idx, reg, expr, asm.template, true, None);
}
hir::InlineAsmOperand::Out { reg, late: _, ref expr } => {
if let Some(expr) = expr {
self.check_asm_operand_type(idx, reg, expr, asm.template, None);
self.check_asm_operand_type(idx, reg, expr, asm.template, false, None);
}
}
hir::InlineAsmOperand::InOut { reg, late: _, ref expr } => {
self.check_asm_operand_type(idx, reg, expr, asm.template, None);
self.check_asm_operand_type(idx, reg, expr, asm.template, false, None);
}
hir::InlineAsmOperand::SplitInOut { reg, late: _, ref in_expr, ref out_expr } => {
let in_ty = self.check_asm_operand_type(idx, reg, in_expr, asm.template, None);
let in_ty =
self.check_asm_operand_type(idx, reg, in_expr, asm.template, true, None);
if let Some(out_expr) = out_expr {
self.check_asm_operand_type(
idx,
reg,
out_expr,
asm.template,
false,
Some((in_expr, in_ty)),
);
}
Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/asm/issue-87802.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// needs-asm-support
// Make sure rustc doesn't ICE on asm! when output type is !.

#![feature(asm)]

fn hmm() -> ! {
let x;
unsafe {
asm!("/* {0} */", out(reg) x);
//~^ ERROR cannot use value of type `!` for inline assembly
}
x
}

fn main() {
hmm();
}
10 changes: 10 additions & 0 deletions src/test/ui/asm/issue-87802.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: cannot use value of type `!` for inline assembly
--> $DIR/issue-87802.rs:9:36
|
LL | asm!("/* {0} */", out(reg) x);
| ^
|
= note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly

error: aborting due to previous error

0 comments on commit 1164f48

Please sign in to comment.