diff options
author | Owen Avery <powerboat9.gamer@gmail.com> | 2023-04-20 13:31:30 -0400 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-01-16 18:34:16 +0100 |
commit | b911f7b85abd3bb96f35d1bd8075a07fd732c71a (patch) | |
tree | 22e06a053d1e5ed21d55054737c88c5bcebcd6e0 /gcc | |
parent | ba534efbc00a4d1b45aea57b8eb35c82fe007780 (diff) | |
download | gcc-b911f7b85abd3bb96f35d1bd8075a07fd732c71a.zip gcc-b911f7b85abd3bb96f35d1bd8075a07fd732c71a.tar.gz gcc-b911f7b85abd3bb96f35d1bd8075a07fd732c71a.tar.bz2 |
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 <powerboat9.gamer@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/expand/rust-macro-substitute-ctx.cc | 18 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/macro52.rs | 11 |
2 files changed, 26 insertions, 3 deletions
diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc index 9592d2d..eb0f149 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 0000000..31002eb --- /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); +} |