From: Owen Avery Date: Thu, 20 Apr 2023 17:31:30 +0000 (-0400) Subject: gccrs: Fix out of bounds indexing while expanding macros with repetition X-Git-Tag: basepoints/gcc-15~2593 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b911f7b85abd3bb96f35d1bd8075a07fd732c71a;p=thirdparty%2Fgcc.git 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 --- 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); +}