Skip to content

Commit

Permalink
Allow unused arguments in asm!
Browse files Browse the repository at this point in the history
  • Loading branch information
Amanieu committed Jun 8, 2020
1 parent a2fc33e commit 5bf2f50
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 60 deletions.
6 changes: 4 additions & 2 deletions src/doc/unstable-book/src/library-features/asm.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ fn mul(a: u64, b: u64) -> u128 {
);
}
(hi as u128) << 64 + lo as u128
((hi as u128) << 64) + lo as u128
}
```

Expand Down Expand Up @@ -382,7 +382,9 @@ The macro will initially be supported only on ARM, AArch64, x86, x86-64 and RISC

The assembler template uses the same syntax as [format strings][format-syntax] (i.e. placeholders are specified by curly braces). The corresponding arguments are accessed in order, by index, or by name. However, implicit named arguments (introduced by [RFC #2795][rfc-2795]) are not supported.

As with format strings, named arguments must appear after positional arguments. Explicit register operands must appear at the end of the operand list, after any named arguments if any. Explicit register operands cannot be used by placeholders in the template string. All other operands must appear at least once in the template string, otherwise a compiler error is generated.
As with format strings, named arguments must appear after positional arguments. Explicit register operands must appear at the end of the operand list, after named arguments if any.

Explicit register operands cannot be used by placeholders in the template string. All other named and positional operands must appear at least once in the template string, otherwise a compiler error is generated.

The exact assembly code syntax is target-specific and opaque to the compiler except for the way operands are substituted into the template string to form the code passed to the assembler.

Expand Down
34 changes: 6 additions & 28 deletions src/librustc_builtin_macros/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
use rustc_expand::base::{self, *};
use rustc_parse::parser::Parser;
use rustc_parse_format as parse;
use rustc_session::lint::builtin::UNUSED_ASM_ARGUMENTS;
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::{InnerSpan, Span};

Expand Down Expand Up @@ -485,34 +486,11 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, sp: Span, args: AsmArgs) -> P<ast
.into_iter()
.enumerate()
.filter(|&(_, used)| !used)
.map(|(idx, _)| {
if named_pos.contains(&idx) {
// named argument
(operands[idx].1, "named argument never used")
} else {
// positional argument
(operands[idx].1, "argument never used")
}
})
.map(|(idx, _)| operands[idx].1)
.collect();
match unused_operands.len() {
0 => {}
1 => {
let (sp, msg) = unused_operands.into_iter().next().unwrap();
let mut err = ecx.struct_span_err(sp, msg);
err.span_label(sp, msg);
err.emit();
}
_ => {
let mut err = ecx.struct_span_err(
unused_operands.iter().map(|&(sp, _)| sp).collect::<Vec<Span>>(),
"multiple unused asm arguments",
);
for (sp, msg) in unused_operands {
err.span_label(sp, msg);
}
err.emit();
}
if !unused_operands.is_empty() {
let msg = format!("asm argument{} not used in template", pluralize!(unused_operands.len()));
ecx.parse_sess.buffer_lint(UNUSED_ASM_ARGUMENTS, unused_operands, ast::CRATE_NODE_ID, &msg);
}

let line_spans = if parser.line_spans.is_empty() {
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_session/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,12 @@ declare_lint! {
"unsafe operations in unsafe functions without an explicit unsafe block are deprecated",
}

declare_lint! {
pub UNUSED_ASM_ARGUMENTS,
Warn,
"inline asm arguments not used in the template string",
}

declare_lint_pass! {
/// Does nothing as a lint pass, but registers some `Lint`s
/// that are used by other parts of the compiler.
Expand Down
8 changes: 5 additions & 3 deletions src/test/ui/asm/bad-template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@ fn main() {
//~^ ERROR invalid reference to argument at index 0
asm!("{1}", in(reg) foo);
//~^ ERROR invalid reference to argument at index 1
//~^^ ERROR argument never used
//~^^ WARN asm argument not used in template
asm!("{a}");
//~^ ERROR there is no argument named `a`
asm!("{}", a = in(reg) foo);
//~^ ERROR invalid reference to argument at index 0
//~^^ ERROR argument never used
//~^^ WARN asm argument not used in template
asm!("{1}", a = in(reg) foo);
//~^ ERROR invalid reference to argument at index 1
//~^^ ERROR named argument never used
//~^^ WARN asm argument not used in template
asm!("{}", in("eax") foo);
//~^ ERROR invalid reference to argument at index 0
asm!("{:foo}", in(reg) foo);
//~^ ERROR asm template modifier must be a single character
asm!("", in(reg) 0, in(reg) 1);
//~^ WARN asm arguments not used in template
}
}
46 changes: 27 additions & 19 deletions src/test/ui/asm/bad-template.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ LL | asm!("{1}", in(reg) foo);
|
= note: there is 1 argument

error: argument never used
--> $DIR/bad-template.rs:10:21
|
LL | asm!("{1}", in(reg) foo);
| ^^^^^^^^^^^ argument never used

error: there is no argument named `a`
--> $DIR/bad-template.rs:13:15
|
Expand All @@ -41,12 +35,6 @@ note: named arguments cannot be referenced by position
LL | asm!("{}", a = in(reg) foo);
| ^^^^^^^^^^^^^^^

error: named argument never used
--> $DIR/bad-template.rs:15:20
|
LL | asm!("{}", a = in(reg) foo);
| ^^^^^^^^^^^^^^^ named argument never used

error: invalid reference to argument at index 1
--> $DIR/bad-template.rs:18:15
|
Expand All @@ -55,12 +43,6 @@ LL | asm!("{1}", a = in(reg) foo);
|
= note: no positional arguments were given

error: named argument never used
--> $DIR/bad-template.rs:18:21
|
LL | asm!("{1}", a = in(reg) foo);
| ^^^^^^^^^^^^^^^ named argument never used

error: invalid reference to argument at index 0
--> $DIR/bad-template.rs:21:15
|
Expand All @@ -82,5 +64,31 @@ error: asm template modifier must be a single character
LL | asm!("{:foo}", in(reg) foo);
| ^^^

error: aborting due to 10 previous errors
warning: asm argument not used in template
--> $DIR/bad-template.rs:10:21
|
LL | asm!("{1}", in(reg) foo);
| ^^^^^^^^^^^
|
= note: `#[warn(unused_asm_arguments)]` on by default

warning: asm argument not used in template
--> $DIR/bad-template.rs:15:20
|
LL | asm!("{}", a = in(reg) foo);
| ^^^^^^^^^^^^^^^

warning: asm argument not used in template
--> $DIR/bad-template.rs:18:21
|
LL | asm!("{1}", a = in(reg) foo);
| ^^^^^^^^^^^^^^^

warning: asm arguments not used in template
--> $DIR/bad-template.rs:25:18
|
LL | asm!("", in(reg) 0, in(reg) 1);
| ^^^^^^^^^ ^^^^^^^^^

error: aborting due to 7 previous errors; 4 warnings emitted

2 changes: 1 addition & 1 deletion src/test/ui/asm/parse-error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ fn main() {
//~^ ERROR arguments are not allowed after options
asm!("{a}", a = const foo, a = const bar);
//~^ ERROR duplicate argument named `a`
//~^^ ERROR argument never used
//~^^ WARN asm argument not used in template
asm!("", a = in("eax") foo);
//~^ ERROR explicit register arguments cannot have names
asm!("{a}", in("eax") foo, a = const bar);
Expand Down
16 changes: 9 additions & 7 deletions src/test/ui/asm/parse-error.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,6 @@ LL | asm!("{a}", a = const foo, a = const bar);
| |
| previously here

error: argument never used
--> $DIR/parse-error.rs:44:36
|
LL | asm!("{a}", a = const foo, a = const bar);
| ^^^^^^^^^^^^^ argument never used

error: explicit register arguments cannot have names
--> $DIR/parse-error.rs:47:18
|
Expand Down Expand Up @@ -158,5 +152,13 @@ LL | asm!("{1}", in("eax") foo, const bar);
| |
| explicit register argument

error: aborting due to 24 previous errors
warning: asm argument not used in template
--> $DIR/parse-error.rs:44:36
|
LL | asm!("{a}", a = const foo, a = const bar);
| ^^^^^^^^^^^^^
|
= note: `#[warn(unused_asm_arguments)]` on by default

error: aborting due to 23 previous errors; 1 warning emitted

0 comments on commit 5bf2f50

Please sign in to comment.