diff options
author | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-03-23 16:50:47 +0100 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2022-03-24 13:07:22 +0100 |
commit | d859ab0146cd0002afc640d406997efb12a50d98 (patch) | |
tree | c59410d587bc2d9226b3bab9b3d8e50df076b319 /gcc/rust/parse/rust-parse.cc | |
parent | 8283724bc24efc0c11960947f2d4e99bc20b3765 (diff) | |
download | gcc-d859ab0146cd0002afc640d406997efb12a50d98.zip gcc-d859ab0146cd0002afc640d406997efb12a50d98.tar.gz gcc-d859ab0146cd0002afc640d406997efb12a50d98.tar.bz2 |
macros: Allow repetitions of tokens in follow-set in follow-set
When checking if a follow-up is valid, we previously always returned
false when comparing with MacroMatchRepetitions. This is however
invalid, as we should be comparing with the first match of the
repetition to be sure.
Diffstat (limited to 'gcc/rust/parse/rust-parse.cc')
-rw-r--r-- | gcc/rust/parse/rust-parse.cc | 53 |
1 files changed, 27 insertions, 26 deletions
diff --git a/gcc/rust/parse/rust-parse.cc b/gcc/rust/parse/rust-parse.cc index 0153b37..50d2efe 100644 --- a/gcc/rust/parse/rust-parse.cc +++ b/gcc/rust/parse/rust-parse.cc @@ -100,6 +100,30 @@ contains (std::vector<T> &vec, T elm) return std::find (vec.begin (), vec.end (), elm) != vec.end (); } +/** + * Avoid UB by calling .front() and .back() on empty containers... + */ + +template <typename T> +static T * +get_back_ptr (std::vector<std::unique_ptr<T>> &values) +{ + if (values.empty ()) + return nullptr; + + return values.back ().get (); +} + +template <typename T> +static T * +get_front_ptr (std::vector<std::unique_ptr<T>> &values) +{ + if (values.empty ()) + return nullptr; + + return values.front ().get (); +} + static bool peculiar_fragment_match_compatible_fragment ( const AST::MacroFragSpec &last_spec, const AST::MacroFragSpec &spec, @@ -196,8 +220,9 @@ peculiar_fragment_match_compatible (AST::MacroMatchFragment &last_match, case AST::MacroMatch::Repetition: { auto repetition = static_cast<AST::MacroMatchRepetition *> (&match); auto &matches = repetition->get_matches (); - if (!matches.empty ()) - error_locus = matches.front ()->get_match_locus (); + auto first_frag = get_front_ptr (matches); + if (first_frag) + return peculiar_fragment_match_compatible (last_match, *first_frag); break; } case AST::MacroMatch::Matcher: { @@ -231,30 +256,6 @@ peculiar_fragment_match_compatible (AST::MacroMatchFragment &last_match, return false; } -/** - * Avoid UB by calling .front() and .back() on empty containers... - */ - -template <typename T> -static T * -get_back_ptr (std::vector<std::unique_ptr<T>> &values) -{ - if (values.empty ()) - return nullptr; - - return values.back ().get (); -} - -template <typename T> -static T * -get_front_ptr (std::vector<std::unique_ptr<T>> &values) -{ - if (values.empty ()) - return nullptr; - - return values.front ().get (); -} - bool is_match_compatible (AST::MacroMatch &last_match, AST::MacroMatch &match) { |