diff options
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 |