@@ -5182,24 +5182,41 @@ static Function* gen_cfun_wrapper(
51825182 std::vector<Type*> fargt_sig (sig.fargt_sig );
51835183
51845184 fargt_sig.insert (fargt_sig.begin () + sig.sret , T_pprjlvalue);
5185+
51855186 // Shift LLVM attributes for parameters one to the right, as
51865187 // we are adding the extra nest parameter after sret arg.
5187- // AttributeList has function attributes and return value
5188- // attributes before the parameter attributes.
5189- if ( attributes.getNumAttrSets () > static_cast < unsigned >( 2 + sig. sret )) {
5190- AttrBuilder toShift;
5191- // Skip past function and return and sret attributes to the first real parameter
5192- for ( auto it = attributes. index_begin () + 2 + sig. sret ; it != attributes. index_end (); ++it) {
5193- AttrBuilder toShiftTemp ( attributes.getAttributes (it));
5194- attributes = attributes. removeAttributes (jl_LLVMContext, it);
5195- attributes = attributes. addAttributes (jl_LLVMContext, it, toShift);
5196- toShift = std::move (toShiftTemp) ;
5188+ std::vector<std::pair< unsigned , AttributeSet>> newAttributes;
5189+ newAttributes. reserve ( attributes. getNumAttrSets () + 1 );
5190+ auto it = attributes.index_begin ();
5191+
5192+ // Skip past non-parameter attributes ( and perhaps parameter return)
5193+ // Beware that function index is ~0U, so can't just replace with <
5194+ for (;it != attributes.index_end (); ++it) {
5195+ if (it != AttributeList::AttrIndex::FunctionIndex &&
5196+ it >= AttributeList::AttrIndex::FirstArgIndex + sig. sret ) {
5197+ break ;
51975198 }
5198- attributes = attributes.addAttributes (jl_LLVMContext, attributes.index_end (), toShift);
5199+ newAttributes.push_back (std::make_pair (it, attributes.getAttributes (it)));
5200+ }
5201+
5202+ // Skip ahead to first parameter (where we may already be, but aren't necessarily)
5203+ it = AttributeList::AttrIndex::FirstArgIndex + sig.sret ;
5204+
5205+ // Add the new nest attribute
5206+ AttrBuilder attrBuilder;
5207+ attrBuilder.addAttribute (Attribute::Nest);
5208+ AttributeSet set (AttributeSet::get (jl_LLVMContext, attrBuilder));
5209+ newAttributes.push_back (std::make_pair (it, set));
5210+
5211+ // Shift forward the rest of the attributes
5212+ // We are now past the magic numbers, so < is ok here.
5213+ for (;it < attributes.index_end (); ++it) {
5214+ newAttributes.push_back (std::make_pair (it + 1 , attributes.getAttributes (it)));
51995215 }
52005216
5217+ // Create the new AttributeList
5218+ attributes = AttributeList::get (jl_LLVMContext, newAttributes);
52015219 functype = FunctionType::get (sig.sret ? T_void : sig.prt , fargt_sig, /* isVa*/ false );
5202- attributes = attributes.addAttribute (jl_LLVMContext, 1 + sig.sret , Attribute::Nest);
52035220 }
52045221 else {
52055222 functype = sig.functype ();
0 commit comments