https://gcc.gnu.org/g:63da1346b05883c4417139b5a716010607b53ec3

commit r15-8179-g63da1346b05883c4417139b5a716010607b53ec3
Author: jjasmine <tanghocle...@gmail.com>
Date:   Wed May 22 02:00:09 2024 -0700

    gccrs: Add checks for duplicate options in inline asm
    
    gcc/rust/ChangeLog:
    
            * expand/rust-macro-builtins-asm.cc (check_and_set):
            Add checks for duplicate options in inline asm
            (parse_options): likewise.
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/inline_asm_illegal_options.rs: New test.

Diff:
---
 gcc/rust/expand/rust-macro-builtins-asm.cc         | 35 +++++++++++++++-------
 .../rust/compile/inline_asm_illegal_options.rs     | 13 ++++++++
 2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc 
b/gcc/rust/expand/rust-macro-builtins-asm.cc
index 443c8a3bce31..68a617ada4dc 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -19,6 +19,17 @@
 #include "rust-macro-builtins-asm.h"
 
 namespace Rust {
+std::map<AST::InlineAsmOptions, std::string> InlineAsmOptionsMap{
+  {AST::InlineAsmOptions::PURE, "pure"},
+  {AST::InlineAsmOptions::NOMEM, "nomem"},
+  {AST::InlineAsmOptions::READONLY, "readonly"},
+  {AST::InlineAsmOptions::PRESERVES_FLAGS, "preserves_flags"},
+  {AST::InlineAsmOptions::NORETURN, "noreturn"},
+  {AST::InlineAsmOptions::NOSTACK, "nostack"},
+  {AST::InlineAsmOptions::MAY_UNWIND, "may_unwind"},
+  {AST::InlineAsmOptions::ATT_SYNTAX, "att_syntax"},
+  {AST::InlineAsmOptions::RAW, "raw"},
+};
 
 int
 parseDirSpec (Parser<MacroInvocLexer> &parser, TokenId last_token_id)
@@ -115,13 +126,15 @@ parse_clobber_abi (Parser<MacroInvocLexer> &parser, 
TokenId last_token_id,
 }
 
 void
-check_and_set (Parser<MacroInvocLexer> &p, AST::InlineAsm &inlineAsm,
+check_and_set (Parser<MacroInvocLexer> &parser, AST::InlineAsm &inlineAsm,
               AST::InlineAsmOptions option)
 {
-  if (inlineAsm.options.count (option) == 1)
+  if (inlineAsm.options.count (option) != 0)
     {
       // TODO: report an error of duplication
-
+      rust_error_at (parser.peek_current_token ()->get_locus (),
+                    "the `%s` option was already provided",
+                    InlineAsmOptionsMap[option].c_str ());
       return;
     }
   else
@@ -189,20 +202,22 @@ parse_options (Parser<MacroInvocLexer> &parser, TokenId 
last_token_id,
          rust_error_at (token->get_locus (),
                         "Unexpected token encountered in parse_options");
        }
-      if (!parser.skip_token (RIGHT_PAREN))
+      if (parser.skip_token (RIGHT_PAREN))
        {
          break;
        }
 
-      if (!parser.skip_token (COMMA))
+      // Parse comma as optional
+      if (parser.skip_token (COMMA))
        {
-         // TODO: If the skip of comma is unsuccessful, which should be
-         // illegal, pleaes emit the correct error.
-         std::cout << "Illegal comma" << std::endl;
+         continue;
+       }
+      else
+       {
+         std::cout << "Sum wrong here, check it out" << std::endl;
+         token = parser.peek_current_token ();
          return -1;
        }
-
-      token = parser.peek_current_token ();
     }
 
   // TODO: Per rust asm.rs regarding options_spans
diff --git a/gcc/testsuite/rust/compile/inline_asm_illegal_options.rs 
b/gcc/testsuite/rust/compile/inline_asm_illegal_options.rs
new file mode 100644
index 000000000000..ee501941af3d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_asm_illegal_options.rs
@@ -0,0 +1,13 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {}
+}
+
+fn main() {
+    unsafe {
+        asm!("nop", options(nomem, nomem)); // { dg-error "the `nomem` option 
was already provided" }
+        asm!("nop", options(noreturn, noreturn)); // { dg-error "the 
`noreturn` option was already provided" }
+    }
+}
\ No newline at end of file

Reply via email to