Skip to content

Improve error message when _ is used for in/inout asm operands #88209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions compiler/rustc_builtin_macros/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ fn parse_args<'a>(
let mut explicit_reg = false;
let op = if !is_global_asm && p.eat_keyword(kw::In) {
let reg = parse_reg(&mut p, &mut explicit_reg)?;
if p.eat_keyword(kw::Underscore) {
let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands");
return Err(err);
}
let expr = p.parse_expr()?;
ast::InlineAsmOperand::In { reg, expr }
} else if !is_global_asm && p.eat_keyword(sym::out) {
Expand All @@ -129,6 +133,10 @@ fn parse_args<'a>(
ast::InlineAsmOperand::Out { reg, expr, late: true }
} else if !is_global_asm && p.eat_keyword(sym::inout) {
let reg = parse_reg(&mut p, &mut explicit_reg)?;
if p.eat_keyword(kw::Underscore) {
let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands");
return Err(err);
}
let expr = p.parse_expr()?;
if p.eat(&token::FatArrow) {
let out_expr =
Expand All @@ -139,6 +147,10 @@ fn parse_args<'a>(
}
} else if !is_global_asm && p.eat_keyword(sym::inlateout) {
let reg = parse_reg(&mut p, &mut explicit_reg)?;
if p.eat_keyword(kw::Underscore) {
let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands");
return Err(err);
}
let expr = p.parse_expr()?;
if p.eat(&token::FatArrow) {
let out_expr =
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/asm/parse-error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ fn main() {
//~^ ERROR asm template must be a string literal
asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
//~^ ERROR asm template must be a string literal
asm!("{}", in(reg) _);
//~^ ERROR _ cannot be used for input operands
asm!("{}", inout(reg) _);
//~^ ERROR _ cannot be used for input operands
asm!("{}", inlateout(reg) _);
//~^ ERROR _ cannot be used for input operands
}
}

Expand Down
68 changes: 43 additions & 25 deletions src/test/ui/asm/parse-error.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -214,162 +214,180 @@ LL | asm!("{1}", format!("{{{}}}", 0), in(reg) foo, out(reg) bar);
|
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)

error: _ cannot be used for input operands
--> $DIR/parse-error.rs:79:28
|
LL | asm!("{}", in(reg) _);
| ^

error: _ cannot be used for input operands
--> $DIR/parse-error.rs:81:31
|
LL | asm!("{}", inout(reg) _);
| ^

error: _ cannot be used for input operands
--> $DIR/parse-error.rs:83:35
|
LL | asm!("{}", inlateout(reg) _);
| ^

error: requires at least a template string argument
--> $DIR/parse-error.rs:84:1
--> $DIR/parse-error.rs:90:1
|
LL | global_asm!();
| ^^^^^^^^^^^^^^

error: asm template must be a string literal
--> $DIR/parse-error.rs:86:13
--> $DIR/parse-error.rs:92:13
|
LL | global_asm!(FOO);
| ^^^

error: expected token: `,`
--> $DIR/parse-error.rs:88:18
--> $DIR/parse-error.rs:94:18
|
LL | global_asm!("{}" FOO);
| ^^^ expected `,`

error: expected operand, options, or additional template string
--> $DIR/parse-error.rs:90:19
--> $DIR/parse-error.rs:96:19
|
LL | global_asm!("{}", FOO);
| ^^^ expected operand, options, or additional template string

error: expected expression, found end of macro arguments
--> $DIR/parse-error.rs:92:24
--> $DIR/parse-error.rs:98:24
|
LL | global_asm!("{}", const);
| ^ expected expression

error: expected one of `,`, `.`, `?`, or an operator, found `FOO`
--> $DIR/parse-error.rs:94:30
--> $DIR/parse-error.rs:100:30
|
LL | global_asm!("{}", const(reg) FOO);
| ^^^ expected one of `,`, `.`, `?`, or an operator

error: expected one of `)`, `att_syntax`, or `raw`, found `FOO`
--> $DIR/parse-error.rs:96:25
--> $DIR/parse-error.rs:102:25
|
LL | global_asm!("", options(FOO));
| ^^^ expected one of `)`, `att_syntax`, or `raw`

error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
--> $DIR/parse-error.rs:98:25
--> $DIR/parse-error.rs:104:25
|
LL | global_asm!("", options(nomem FOO));
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`

error: expected one of `)`, `att_syntax`, or `raw`, found `nomem`
--> $DIR/parse-error.rs:100:25
--> $DIR/parse-error.rs:106:25
|
LL | global_asm!("", options(nomem, FOO));
| ^^^^^ expected one of `)`, `att_syntax`, or `raw`

error: arguments are not allowed after options
--> $DIR/parse-error.rs:102:30
--> $DIR/parse-error.rs:108:30
|
LL | global_asm!("{}", options(), const FOO);
| --------- ^^^^^^^^^ argument
| |
| previous options

error: expected string literal
--> $DIR/parse-error.rs:104:29
--> $DIR/parse-error.rs:110:29
|
LL | global_asm!("", clobber_abi(FOO));
| ^^^ not a string literal

error: expected `)`, found `FOO`
--> $DIR/parse-error.rs:106:33
--> $DIR/parse-error.rs:112:33
|
LL | global_asm!("", clobber_abi("C" FOO));
| ^^^ expected `)`

error: expected `)`, found `,`
--> $DIR/parse-error.rs:108:32
--> $DIR/parse-error.rs:114:32
|
LL | global_asm!("", clobber_abi("C", FOO));
| ^ expected `)`

error: arguments are not allowed after clobber_abi
--> $DIR/parse-error.rs:110:37
--> $DIR/parse-error.rs:116:37
|
LL | global_asm!("{}", clobber_abi("C"), const FOO);
| ---------------- ^^^^^^^^^ argument
| |
| clobber_abi

error: `clobber_abi` cannot be used with `global_asm!`
--> $DIR/parse-error.rs:110:19
--> $DIR/parse-error.rs:116:19
|
LL | global_asm!("{}", clobber_abi("C"), const FOO);
| ^^^^^^^^^^^^^^^^

error: clobber_abi is not allowed after options
--> $DIR/parse-error.rs:113:28
--> $DIR/parse-error.rs:119:28
|
LL | global_asm!("", options(), clobber_abi("C"));
| --------- ^^^^^^^^^^^^^^^^
| |
| options

error: clobber_abi is not allowed after options
--> $DIR/parse-error.rs:115:30
--> $DIR/parse-error.rs:121:30
|
LL | global_asm!("{}", options(), clobber_abi("C"), const FOO);
| --------- ^^^^^^^^^^^^^^^^
| |
| options

error: clobber_abi specified multiple times
--> $DIR/parse-error.rs:117:35
--> $DIR/parse-error.rs:123:35
|
LL | global_asm!("", clobber_abi("C"), clobber_abi("C"));
| ---------------- ^^^^^^^^^^^^^^^^
| |
| clobber_abi previously specified here

error: duplicate argument named `a`
--> $DIR/parse-error.rs:119:35
--> $DIR/parse-error.rs:125:35
|
LL | global_asm!("{a}", a = const FOO, a = const BAR);
| ------------- ^^^^^^^^^^^^^ duplicate argument
| |
| previously here

error: argument never used
--> $DIR/parse-error.rs:119:35
--> $DIR/parse-error.rs:125:35
|
LL | global_asm!("{a}", a = const FOO, a = const BAR);
| ^^^^^^^^^^^^^ argument never used
|
= help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {1} */"`

error: expected one of `clobber_abi`, `const`, or `options`, found `""`
--> $DIR/parse-error.rs:122:28
--> $DIR/parse-error.rs:128:28
|
LL | global_asm!("", options(), "");
| ^^ expected one of `clobber_abi`, `const`, or `options`

error: expected one of `clobber_abi`, `const`, or `options`, found `"{}"`
--> $DIR/parse-error.rs:124:30
--> $DIR/parse-error.rs:130:30
|
LL | global_asm!("{}", const FOO, "{}", const FOO);
| ^^^^ expected one of `clobber_abi`, `const`, or `options`

error: asm template must be a string literal
--> $DIR/parse-error.rs:126:13
--> $DIR/parse-error.rs:132:13
|
LL | global_asm!(format!("{{{}}}", 0), const FOO);
| ^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)

error: asm template must be a string literal
--> $DIR/parse-error.rs:128:20
--> $DIR/parse-error.rs:134:20
|
LL | global_asm!("{1}", format!("{{{}}}", 0), const FOO, const BAR);
| ^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -439,6 +457,6 @@ LL | let mut bar = 0;
LL | asm!("{1}", in("eax") foo, const bar);
| ^^^ non-constant value

error: aborting due to 63 previous errors
error: aborting due to 66 previous errors

For more information about this error, try `rustc --explain E0435`.