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 | |
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')
-rw-r--r-- | gcc/rust/parse/rust-parse.cc | 53 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/macro-issue1053-2.rs | 5 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/macro-issue1053.rs | 3 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/macro28.rs | 2 |
4 files changed, 36 insertions, 27 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) { diff --git a/gcc/testsuite/rust/compile/macro-issue1053-2.rs b/gcc/testsuite/rust/compile/macro-issue1053-2.rs new file mode 100644 index 0000000..3145990 --- /dev/null +++ b/gcc/testsuite/rust/compile/macro-issue1053-2.rs @@ -0,0 +1,5 @@ +macro_rules! m { + ($e:expr $(forbidden)*) => {{}}; // { dg-error "token .identifier. is not allowed after .expr. fragment" } + // { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-1 } + // { dg-error "failed to parse item in crate" "" { target *-*-* } .-2 } +} diff --git a/gcc/testsuite/rust/compile/macro-issue1053.rs b/gcc/testsuite/rust/compile/macro-issue1053.rs new file mode 100644 index 0000000..1e96849 --- /dev/null +++ b/gcc/testsuite/rust/compile/macro-issue1053.rs @@ -0,0 +1,3 @@ +macro_rules! m { + ($e:expr $(,)*) => {{}}; +} diff --git a/gcc/testsuite/rust/compile/macro28.rs b/gcc/testsuite/rust/compile/macro28.rs index 3d83c08..8002f28 100644 --- a/gcc/testsuite/rust/compile/macro28.rs +++ b/gcc/testsuite/rust/compile/macro28.rs @@ -1,6 +1,6 @@ macro_rules! m { ($a:expr $(tok $es:expr)*) => { - // { dg-error "fragment is not allowed after .expr. fragment" "" { target *-*-* } .-1 } + // { dg-error "token .identifier. is not allowed after .expr. fragment" "" { target *-*-* } .-1 } // { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .-2 } // { dg-error "failed to parse item in crate" "" { target *-*-* } .-3 } $a |