diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-03-18 13:20:09 +0100 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-03-18 14:09:03 +0100 |
commit | f8c550f7e19c79c98f6d21ad6ce68d615451459a (patch) | |
tree | 45f589d179aa8c9f98a282e9a60999aef214d816 /gcc | |
parent | 1bb9a29688ab4ddfec7f8d36ca2cee63c5f258d2 (diff) | |
download | gcc-f8c550f7e19c79c98f6d21ad6ce68d615451459a.zip gcc-f8c550f7e19c79c98f6d21ad6ce68d615451459a.tar.gz gcc-f8c550f7e19c79c98f6d21ad6ce68d615451459a.tar.bz2 |
macros: Only expand merged repetitions if they contain the same amount
of matches
Forbid merging repetitions if the matched fragments do not contain the
same amount of repetitions
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/expand/rust-macro-substitute-ctx.cc | 55 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-substitute-ctx.h | 11 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/macro26.rs | 10 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/macros24.rs | 9 |
4 files changed, 71 insertions, 14 deletions
diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc index 392a9fe..a6933bb 100644 --- a/gcc/rust/expand/rust-macro-substitute-ctx.cc +++ b/gcc/rust/expand/rust-macro-substitute-ctx.cc @@ -30,18 +30,14 @@ SubstituteCtx::substitute_metavar (std::unique_ptr<AST::Token> &metavar) return expanded; } -std::vector<std::unique_ptr<AST::Token>> -SubstituteCtx::substitute_repetition ( - size_t pattern_start, size_t pattern_end, - std::unique_ptr<AST::Token> separator_token) +bool +SubstituteCtx::check_repetition_amount (size_t pattern_start, + size_t pattern_end, + size_t &expected_repetition_amount) { - rust_assert (pattern_end < macro.size ()); - - std::vector<std::unique_ptr<AST::Token>> expanded; + bool first_fragment_found = false; + bool is_valid = true; - // Find the first fragment and get the amount of repetitions that we should - // perform - size_t repeat_amount = 0; for (size_t i = pattern_start; i < pattern_end; i++) { if (macro.at (i)->get_id () == DOLLAR_SIGN) @@ -59,17 +55,48 @@ SubstituteCtx::substitute_repetition ( rust_error_at (frag_token->get_locus (), "metavar %s used in repetition does not exist", frag_token->get_str ().c_str ()); - // FIXME: - return expanded; + + is_valid = false; } - // FIXME: Refactor, ugly - repeat_amount = it->second.get_match_amount (); + size_t repeat_amount = it->second.get_match_amount (); + if (!first_fragment_found) + { + first_fragment_found = true; + expected_repetition_amount = repeat_amount; + } + else + { + if (repeat_amount != expected_repetition_amount) + { + rust_error_at ( + frag_token->get_locus (), + "different amount of matches used in merged " + "repetitions: expected %ld, got %ld", + expected_repetition_amount, repeat_amount); + is_valid = false; + } + } } } } + return is_valid; +} + +std::vector<std::unique_ptr<AST::Token>> +SubstituteCtx::substitute_repetition ( + size_t pattern_start, size_t pattern_end, + std::unique_ptr<AST::Token> separator_token) +{ + rust_assert (pattern_end < macro.size ()); + + size_t repeat_amount = 0; + if (!check_repetition_amount (pattern_start, pattern_end, repeat_amount)) + return {}; + rust_debug ("repetition amount to use: %lu", repeat_amount); + std::vector<std::unique_ptr<AST::Token>> expanded; std::vector<std::unique_ptr<AST::Token>> new_macro; // We want to generate a "new macro" to substitute with. This new macro diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.h b/gcc/rust/expand/rust-macro-substitute-ctx.h index e89f9d7..81dcab7 100644 --- a/gcc/rust/expand/rust-macro-substitute-ctx.h +++ b/gcc/rust/expand/rust-macro-substitute-ctx.h @@ -26,6 +26,17 @@ class SubstituteCtx std::vector<std::unique_ptr<AST::Token>> ¯o; std::map<std::string, MatchedFragmentContainer> &fragments; + /** + * Find the repetition amount to use when expanding a repetition, and + * check that all fragments used respect that repetition amount + * + * @param pattern_start Start of the repetition pattern + * @param pattern_end End of the repetition pattern + * @param repeat_amount Reference to fill with the matched repetition amount + */ + bool check_repetition_amount (size_t pattern_start, size_t pattern_end, + size_t &repeat_amount); + public: SubstituteCtx (std::vector<std::unique_ptr<AST::Token>> &input, std::vector<std::unique_ptr<AST::Token>> ¯o, diff --git a/gcc/testsuite/rust/compile/macro26.rs b/gcc/testsuite/rust/compile/macro26.rs new file mode 100644 index 0000000..f6588e7 --- /dev/null +++ b/gcc/testsuite/rust/compile/macro26.rs @@ -0,0 +1,10 @@ +macro_rules! repeat { + ( $( $i:literal ),* ; $( $j:literal ),* ) => (( $( ($i,$j) ),* )) + // { dg-error "different amount of matches used in merged repetitions" "" { target *-*-* } .-1 } +} + +fn main() -> i32 { + let _ = repeat!(1, 2, 3; 2, 3); + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros24.rs b/gcc/testsuite/rust/execute/torture/macros24.rs new file mode 100644 index 0000000..f838a83 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros24.rs @@ -0,0 +1,9 @@ +macro_rules! repeat { + ( $( $i:literal ),* ; $( $j:literal ),* ) => (( $( ($i,$j) ),* )) +} + +fn main() -> i32 { + let t = repeat!(1, 1; 2, 2); + + t.0 .0 + t.0 .1 + t.1 .0 + t.1 .1 - 6 +} |