Hi,

On Tue, Jul 13 2021, Alexandre Oliva wrote:
> 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?

I agree that there is a mismatch but I do not like proposed change.
Indeed fill_vector_of_new_param_types can skip some parameters when they
appear to be copies of something that is not there - but that bail-out
is not supposed to ever happen when fill_vector_of_new_param_types is
called from ipa_param_body_adjustments.

It is there for cases where one compilation unit has a completely bogus
idea of a type defined in another compilation unit and so creates a bad
type for gimple_call_fntype, but then LTO decides to do something with
the parameters and modifying the gimple_call_fntype becomes a
garbage-in-garbage-out operation (but avoids ICE).

That should never happen when you actually have a body and so presumably
the type and parameters match.  So I would first check how come that you
request IPA_PARAM_OP_COPY of something that does not seem to have a
corresponding type but there is a DECL, otherwise the code would have
ICEd when attempting to "carry over" that.

If you believe that what you're doing is correct (but check twice), I
would prefer the following change (only mildly tested) that is a
clean-up and should help you with your problem too.

Thanks,

Martin


diff --git a/gcc/ipa-param-manipulation.c b/gcc/ipa-param-manipulation.c
index 26b02d7aa95..c5285b7cdf3 100644
--- a/gcc/ipa-param-manipulation.c
+++ b/gcc/ipa-param-manipulation.c
@@ -1067,14 +1067,15 @@ ipa_param_body_adjustments::common_initialization (tree 
old_fndecl,
   auto_vec<tree,16> otypes;
   if (TYPE_ARG_TYPES (TREE_TYPE (old_fndecl)) != NULL_TREE)
     push_function_arg_types (&otypes, TREE_TYPE (old_fndecl));
-  else
+  if (m_oparms.length () != otypes.length ())
     {
-      auto_vec<tree,16> oparms;
-      push_function_arg_decls (&oparms, old_fndecl);
-      unsigned ocount = oparms.length ();
+      /* Parameter type information is not available or there is a mismatch
+        between it and the real parameters (probably K&R code or weird LTO
+        mismatched decls).  */
+      unsigned ocount = m_oparms.length ();
       otypes.reserve_exact (ocount);
       for (unsigned i = 0; i < ocount; i++)
-       otypes.quick_push (TREE_TYPE (oparms[i]));
+       otypes.quick_push (TREE_TYPE (m_oparms[i]));
     }
   fill_vector_of_new_param_types (&m_new_types, &otypes, m_adj_params, true);

Reply via email to