From b911f7b85abd3bb96f35d1bd8075a07fd732c71a Mon Sep 17 00:00:00 2001 From: Owen Avery Date: Thu, 20 Apr 2023 13:31:30 -0400 Subject: [PATCH] gccrs: Fix out of bounds indexing while expanding macros with repetition gcc/rust/ChangeLog: * expand/rust-macro-substitute-ctx.cc (SubstituteCtx::substitute_repetition): Fix out-of-bounds. gcc/testsuite/ChangeLog: * rust/compile/macro52.rs: New test. Signed-off-by: Owen Avery --- gcc/rust/expand/rust-macro-substitute-ctx.cc | 18 +++++++++++++++--- gcc/testsuite/rust/compile/macro52.rs | 11 +++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/rust/compile/macro52.rs diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc index 9592d2d2a9e1..eb0f149b10ad 100644 --- a/gcc/rust/expand/rust-macro-substitute-ctx.cc +++ b/gcc/rust/expand/rust-macro-substitute-ctx.cc @@ -147,15 +147,27 @@ SubstituteCtx::substitute_repetition ( { MatchedFragment sub_fragment; + // Hack: A repeating meta variable might not be present in the new + // macro. Don't include this match if the fragment doesn't have enough + // items, as check_repetition_amount should prevent repetition amount + // mismatches anyway. + bool is_used = true; + // FIXME: Hack: If a fragment is not repeated, how does it fit in the // submap? Do we really want to expand it? Is this normal behavior? if (kv_match.second.is_single_fragment ()) sub_fragment = kv_match.second.get_single_fragment (); else - sub_fragment = kv_match.second.get_fragments ()[i]; + { + if (kv_match.second.get_fragments ().size () > i) + sub_fragment = kv_match.second.get_fragments ().at (i); + else + is_used = false; + } - sub_map.insert ( - {kv_match.first, MatchedFragmentContainer::metavar (sub_fragment)}); + if (is_used) + sub_map.insert ({kv_match.first, + MatchedFragmentContainer::metavar (sub_fragment)}); } auto substitute_context = SubstituteCtx (input, new_macro, sub_map); diff --git a/gcc/testsuite/rust/compile/macro52.rs b/gcc/testsuite/rust/compile/macro52.rs new file mode 100644 index 000000000000..31002eb8e15c --- /dev/null +++ b/gcc/testsuite/rust/compile/macro52.rs @@ -0,0 +1,11 @@ +macro_rules! multi { + ($( $a:ident )? $( + $b:ident )?) => { + { + $( let $a: u32 )?; + } + } +} + +pub fn foo() { + multi!(_a); +} -- 2.47.2