The logic in fill_vector_of_new_param_types may skip some parameters when pushing into m_new_types, but common_initialization doesn't take that into account, and may end up attempting to access the vector past its end when IPA_PARAM_OP_(NEW|SPLIT) operands appear after skipped _COPY ones.
This patch adjusts the consumer logic to match the indexing in the producer. It came up in libstdc++-v3's testsuite, in std/ranges/adaptors/filter.cc, but only with wrappers introduced by a pass I'm working on. The _NEW parameters were reference-typed replacements for some by-value ones in my function-wrapping logic, and other IPA transformations cause plenty of unused/irrelevant arguments to be dropped for certain calls. Regstrapped on x86_64-linux-gnu. Ok to install? for gcc/ChangeLog * ipa-param-manipulation.c (ipa_param_body_adjustments::common_initialization): Adjust m_new_types indexing to match producer. --- gcc/ipa-param-manipulation.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gcc/ipa-param-manipulation.c b/gcc/ipa-param-manipulation.c index 75b5a47a7ae8b..dbbe547832dc5 100644 --- a/gcc/ipa-param-manipulation.c +++ b/gcc/ipa-param-manipulation.c @@ -1102,11 +1102,17 @@ ipa_param_body_adjustments::common_initialization (tree old_fndecl, corresponding m_id->dst_node->clone.performed_splits entries. */ m_new_decls.reserve_exact (adj_len); - for (unsigned i = 0; i < adj_len ; i++) + for (unsigned i = 0, nti = 0; i < adj_len ; i++, nti++) { ipa_adjusted_param *apm = &(*m_adj_params)[i]; unsigned prev_index = apm->prev_clone_index; tree new_parm; + if (apm->op == IPA_PARAM_OP_COPY + && prev_index >= otypes.length ()) + /* Keep nti in sync with the m_new_types indices used in + fill_vector_of_new_param_types, for any non-IPA_PARAM_OP_COPY + parms. */ + nti--; if (apm->op == IPA_PARAM_OP_COPY || apm->prev_clone_adjustment) { @@ -1117,7 +1123,7 @@ ipa_param_body_adjustments::common_initialization (tree old_fndecl, else if (apm->op == IPA_PARAM_OP_NEW || apm->op == IPA_PARAM_OP_SPLIT) { - tree new_type = m_new_types[i]; + tree new_type = m_new_types[nti]; gcc_checking_assert (new_type); new_parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE, new_type); -- Alexandre Oliva, happy hacker https://FSFLA.org/blogs/lxo/ Free Software Activist GNU Toolchain Engineer Disinformation flourishes because many people care deeply about injustice but very few check the facts. Ask me about <https://stallmansupport.org>