aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/parse/rust-parse.cc
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2022-03-23 16:50:47 +0100
committerArthur Cohen <arthur.cohen@embecosm.com>2022-03-24 13:07:22 +0100
commitd859ab0146cd0002afc640d406997efb12a50d98 (patch)
treec59410d587bc2d9226b3bab9b3d8e50df076b319 /gcc/rust/parse/rust-parse.cc
parent8283724bc24efc0c11960947f2d4e99bc20b3765 (diff)
downloadgcc-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.cc53
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)
{