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);