@@ -5182,24 +5182,40 @@ 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.emplace_back (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+ newAttributes.emplace_back (it, AttributeSet::get (jl_LLVMContext, attrBuilder));
5209+
5210+ // Shift forward the rest of the attributes
5211+ // We are now past the magic numbers, so < is ok here.
5212+ for (;it < attributes.index_end (); ++it) {
5213+ newAttributes.emplace_back (it + 1 , attributes.getAttributes (it));
51995214 }
52005215
5216+ // Create the new AttributeList
5217+ attributes = AttributeList::get (jl_LLVMContext, newAttributes);
52015218 functype = FunctionType::get (sig.sret ? T_void : sig.prt , fargt_sig, /* isVa*/ false );
5202- attributes = attributes.addAttribute (jl_LLVMContext, 1 + sig.sret , Attribute::Nest);
52035219 }
52045220 else {
52055221 functype = sig.functype ();
0 commit comments