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>

Reply via email to