]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix handling of single fragments in repetitions
authorOwen Avery <powerboat9.gamer@gmail.com>
Mon, 29 May 2023 03:44:57 +0000 (23:44 -0400)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:37:22 +0000 (18:37 +0100)
gcc/rust/ChangeLog:

* expand/rust-macro-substitute-ctx.cc
(SubstituteCtx::check_repetition_amount):
Ignore single fragments while checking repetition amount.

gcc/testsuite/ChangeLog:

* rust/compile/issue-2207.rs: New test.

Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
gcc/rust/expand/rust-macro-substitute-ctx.cc
gcc/testsuite/rust/compile/issue-2207.rs [new file with mode: 0644]

index 0a38578bd74a483b13df891ca41b708fb14aa5cd..85c9d7e01764df22ffeb66751f6b0a48fc6fe025 100644 (file)
@@ -77,31 +77,33 @@ SubstituteCtx::check_repetition_amount (size_t pattern_start,
 
              auto &fragment = it->second;
 
-             size_t repeat_amount = fragment.get_match_amount ();
-             if (!first_fragment_found)
+             if (!fragment.is_single_fragment ())
                {
-                 first_fragment_found = true;
-                 expected_repetition_amount = repeat_amount;
-               }
-             else
-               {
-                 if (repeat_amount != expected_repetition_amount
-                     && !fragment.is_single_fragment ())
+                 size_t repeat_amount = fragment.get_match_amount ();
+                 if (!first_fragment_found)
+                   {
+                     first_fragment_found = true;
+                     expected_repetition_amount = repeat_amount;
+                   }
+                 else
                    {
-                     rust_error_at (
-                       frag_token->get_locus (),
-                       "different amount of matches used in merged "
-                       "repetitions: expected %lu, got %lu",
-                       (unsigned long) expected_repetition_amount,
-                       (unsigned long) repeat_amount);
-                     is_valid = false;
+                     if (repeat_amount != expected_repetition_amount)
+                       {
+                         rust_error_at (
+                           frag_token->get_locus (),
+                           "different amount of matches used in merged "
+                           "repetitions: expected %lu, got %lu",
+                           (unsigned long) expected_repetition_amount,
+                           (unsigned long) repeat_amount);
+                         is_valid = false;
+                       }
                    }
                }
            }
        }
     }
 
-  return is_valid;
+  return is_valid && first_fragment_found;
 }
 
 std::vector<std::unique_ptr<AST::Token>>
diff --git a/gcc/testsuite/rust/compile/issue-2207.rs b/gcc/testsuite/rust/compile/issue-2207.rs
new file mode 100644 (file)
index 0000000..cdc64fa
--- /dev/null
@@ -0,0 +1,12 @@
+macro_rules! finish {
+    (+ - + * + /) => {}
+}
+
+macro_rules! foo {
+    () => { foo!(+ - * /); };
+    ($a:tt $($b:tt)*) => { finish!($($a $b)*); }
+}
+
+pub fn bar() {
+    foo!();
+}