about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-10-07 11:51:51 +0000
committerbors <bors@rust-lang.org>2020-10-07 11:51:51 +0000
commita14bf4862df2749917a3eed7a44d420b8fa4e55d (patch)
tree2180edc04a7a5b3603db713a0cbe614f90d7516e
parent8ae3b509768774a9d351b939d18d5cb421b6ed3b (diff)
parent219c66c55c86db51a1a278c2d3cb7f8a1f4426e9 (diff)
downloadrust-a14bf4862df2749917a3eed7a44d420b8fa4e55d.tar.gz
rust-a14bf4862df2749917a3eed7a44d420b8fa4e55d.zip
Auto merge of #77595 - petrochenkov:asmident, r=oli-obk
builtin_macros: Fix use of interpolated identifiers in `asm!`

Fixes https://github.com/rust-lang/rust/issues/77584
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs35
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs3
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--src/test/ui/asm/interpolated-idents.rs24
-rw-r--r--src/test/ui/asm/interpolated-idents.stderr51
5 files changed, 95 insertions, 20 deletions
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 09985959b67..36cd6c281b4 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -81,7 +81,7 @@ fn parse_args<'a>(
         } // accept trailing commas
 
         // Parse options
-        if p.eat(&token::Ident(sym::options, false)) {
+        if p.eat_keyword(sym::options) {
             parse_options(&mut p, &mut args)?;
             allow_templates = false;
             continue;
@@ -101,19 +101,19 @@ fn parse_args<'a>(
         };
 
         let mut explicit_reg = false;
-        let op = if p.eat(&token::Ident(kw::In, false)) {
+        let op = if p.eat_keyword(kw::In) {
             let reg = parse_reg(&mut p, &mut explicit_reg)?;
             let expr = p.parse_expr()?;
             ast::InlineAsmOperand::In { reg, expr }
-        } else if p.eat(&token::Ident(sym::out, false)) {
+        } else if p.eat_keyword(sym::out) {
             let reg = parse_reg(&mut p, &mut explicit_reg)?;
             let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
             ast::InlineAsmOperand::Out { reg, expr, late: false }
-        } else if p.eat(&token::Ident(sym::lateout, false)) {
+        } else if p.eat_keyword(sym::lateout) {
             let reg = parse_reg(&mut p, &mut explicit_reg)?;
             let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
             ast::InlineAsmOperand::Out { reg, expr, late: true }
-        } else if p.eat(&token::Ident(sym::inout, false)) {
+        } else if p.eat_keyword(sym::inout) {
             let reg = parse_reg(&mut p, &mut explicit_reg)?;
             let expr = p.parse_expr()?;
             if p.eat(&token::FatArrow) {
@@ -123,7 +123,7 @@ fn parse_args<'a>(
             } else {
                 ast::InlineAsmOperand::InOut { reg, expr, late: false }
             }
-        } else if p.eat(&token::Ident(sym::inlateout, false)) {
+        } else if p.eat_keyword(sym::inlateout) {
             let reg = parse_reg(&mut p, &mut explicit_reg)?;
             let expr = p.parse_expr()?;
             if p.eat(&token::FatArrow) {
@@ -133,10 +133,10 @@ fn parse_args<'a>(
             } else {
                 ast::InlineAsmOperand::InOut { reg, expr, late: true }
             }
-        } else if p.eat(&token::Ident(kw::Const, false)) {
+        } else if p.eat_keyword(kw::Const) {
             let expr = p.parse_expr()?;
             ast::InlineAsmOperand::Const { expr }
-        } else if p.eat(&token::Ident(sym::sym, false)) {
+        } else if p.eat_keyword(sym::sym) {
             let expr = p.parse_expr()?;
             match expr.kind {
                 ast::ExprKind::Path(..) => {}
@@ -164,7 +164,7 @@ fn parse_args<'a>(
             args.templates.push(template);
             continue;
         } else {
-            return Err(p.expect_one_of(&[], &[]).unwrap_err());
+            return p.unexpected();
         };
 
         allow_templates = false;
@@ -333,21 +333,22 @@ fn parse_options<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> Result<(), Diagn
     p.expect(&token::OpenDelim(token::DelimToken::Paren))?;
 
     while !p.eat(&token::CloseDelim(token::DelimToken::Paren)) {
-        if p.eat(&token::Ident(sym::pure, false)) {
+        if p.eat_keyword(sym::pure) {
             try_set_option(p, args, sym::pure, ast::InlineAsmOptions::PURE);
-        } else if p.eat(&token::Ident(sym::nomem, false)) {
+        } else if p.eat_keyword(sym::nomem) {
             try_set_option(p, args, sym::nomem, ast::InlineAsmOptions::NOMEM);
-        } else if p.eat(&token::Ident(sym::readonly, false)) {
+        } else if p.eat_keyword(sym::readonly) {
             try_set_option(p, args, sym::readonly, ast::InlineAsmOptions::READONLY);
-        } else if p.eat(&token::Ident(sym::preserves_flags, false)) {
+        } else if p.eat_keyword(sym::preserves_flags) {
             try_set_option(p, args, sym::preserves_flags, ast::InlineAsmOptions::PRESERVES_FLAGS);
-        } else if p.eat(&token::Ident(sym::noreturn, false)) {
+        } else if p.eat_keyword(sym::noreturn) {
             try_set_option(p, args, sym::noreturn, ast::InlineAsmOptions::NORETURN);
-        } else if p.eat(&token::Ident(sym::nostack, false)) {
+        } else if p.eat_keyword(sym::nostack) {
             try_set_option(p, args, sym::nostack, ast::InlineAsmOptions::NOSTACK);
-        } else {
-            p.expect(&token::Ident(sym::att_syntax, false))?;
+        } else if p.eat_keyword(sym::att_syntax) {
             try_set_option(p, args, sym::att_syntax, ast::InlineAsmOptions::ATT_SYNTAX);
+        } else {
+            return p.unexpected();
         }
 
         // Allow trailing commas
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index 25181715540..5bfd8a2bf56 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -120,8 +120,7 @@ fn parse_assert<'a>(
         };
 
     if parser.token != token::Eof {
-        parser.expect_one_of(&[], &[])?;
-        unreachable!();
+        return parser.unexpected();
     }
 
     Ok(Assert { cond_expr, custom_message })
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 7340c574480..070fc140ec4 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -386,7 +386,7 @@ impl<'a> Parser<'a> {
         next
     }
 
-    crate fn unexpected<T>(&mut self) -> PResult<'a, T> {
+    pub fn unexpected<T>(&mut self) -> PResult<'a, T> {
         match self.expect_one_of(&[], &[]) {
             Err(e) => Err(e),
             // We can get `Ok(true)` from `recover_closing_delimiter`
diff --git a/src/test/ui/asm/interpolated-idents.rs b/src/test/ui/asm/interpolated-idents.rs
new file mode 100644
index 00000000000..f4cb749307d
--- /dev/null
+++ b/src/test/ui/asm/interpolated-idents.rs
@@ -0,0 +1,24 @@
+// only-x86_64
+
+#![feature(asm)]
+
+macro_rules! m {
+    ($in:ident $out:ident $lateout:ident $inout:ident $inlateout:ident $const:ident $sym:ident
+     $pure:ident $nomem:ident $readonly:ident $preserves_flags:ident
+     $noreturn:ident $nostack:ident $att_syntax:ident $options:ident) => {
+        unsafe {
+            asm!("", $in(x) x, $out(x) x, $lateout(x) x, $inout(x) x, $inlateout(x) x,
+            //~^ ERROR asm outputs are not allowed with the `noreturn` option
+            const x, sym x,
+            $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack, $att_syntax));
+            //~^ ERROR the `nomem` and `readonly` options are mutually exclusive
+            //~| ERROR the `pure` and `noreturn` options are mutually exclusive
+        }
+    };
+}
+
+fn main() {
+    m!(in out lateout inout inlateout const sym
+       pure nomem readonly preserves_flags
+       noreturn nostack att_syntax options);
+}
diff --git a/src/test/ui/asm/interpolated-idents.stderr b/src/test/ui/asm/interpolated-idents.stderr
new file mode 100644
index 00000000000..6ffe8d97b05
--- /dev/null
+++ b/src/test/ui/asm/interpolated-idents.stderr
@@ -0,0 +1,51 @@
+error: the `nomem` and `readonly` options are mutually exclusive
+  --> $DIR/interpolated-idents.rs:13:13
+   |
+LL |               $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack, $att_syntax));
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | /     m!(in out lateout inout inlateout const sym
+LL | |        pure nomem readonly preserves_flags
+LL | |        noreturn nostack att_syntax options);
+   | |____________________________________________- in this macro invocation
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: the `pure` and `noreturn` options are mutually exclusive
+  --> $DIR/interpolated-idents.rs:13:13
+   |
+LL |               $options($pure, $nomem, $readonly, $preserves_flags, $noreturn, $nostack, $att_syntax));
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | /     m!(in out lateout inout inlateout const sym
+LL | |        pure nomem readonly preserves_flags
+LL | |        noreturn nostack att_syntax options);
+   | |____________________________________________- in this macro invocation
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: asm outputs are not allowed with the `noreturn` option
+  --> $DIR/interpolated-idents.rs:10:32
+   |
+LL |               asm!("", $in(x) x, $out(x) x, $lateout(x) x, $inout(x) x, $inlateout(x) x,
+   |                                  ^^^^^^^^^  ^^^^^^^^^^^^^  ^^^^^^^^^^^  ^^^^^^^^^^^^^^^
+...
+LL |       m!(in out lateout inout inlateout const sym
+   |  _____-
+   | |_____|
+   | |_____|
+   | |_____|
+   | |
+LL | |        pure nomem readonly preserves_flags
+LL | |        noreturn nostack att_syntax options);
+   | |                                            -
+   | |____________________________________________|
+   | |____________________________________________in this macro invocation
+   | |____________________________________________in this macro invocation
+   | |____________________________________________in this macro invocation
+   |                                              in this macro invocation
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+