]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Add checks for duplicate options in inline asm
authorjjasmine <tanghocle456@gmail.com>
Wed, 22 May 2024 09:00:09 +0000 (02:00 -0700)
committerArthur Cohen <arthur.cohen@embecosm.com>
Mon, 17 Mar 2025 15:35:40 +0000 (16:35 +0100)
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.

gcc/rust/expand/rust-macro-builtins-asm.cc
gcc/testsuite/rust/compile/inline_asm_illegal_options.rs [new file with mode: 0644]

index 443c8a3bce31ea6c558f25fc84197bb50c186866..68a617ada4dc8723f3172ace3881a34c015e71a2 100644 (file)
 #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 (file)
index 0000000..ee50194
--- /dev/null
@@ -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