Skip to content

Commit

Permalink
Parameter attributes on Cfunction closures sticks
Browse files Browse the repository at this point in the history
When CFunction closures are created an extra argument is added to the
function signature for holding the closure.

Make sure that the parameter attributes on already existing parameters
are not shifted when adding that parameter.
  • Loading branch information
troels committed Aug 8, 2021
1 parent 0e8bb95 commit cae5325
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
20 changes: 17 additions & 3 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5169,9 +5169,23 @@ static Function* gen_cfun_wrapper(
// add nest parameter (pointer to jl_value_t* data array) after sret arg
assert(closure_types);
std::vector<Type*> fargt_sig(sig.fargt_sig);
fargt_sig.insert(fargt_sig.begin() + sig.sret, T_pprjlvalue);
functype = FunctionType::get(sig.sret ? T_void : sig.prt, fargt_sig, /*isVa*/false);
attributes = attributes.addAttribute(jl_LLVMContext, 1 + sig.sret, Attribute::Nest);

fargt_sig.insert(fargt_sig.begin() + sig.sret, T_pprjlvalue);
// Shift LLVM attributes for parameters one to the right, as we are adding the extra nest parameter
// after sret arg.
if (attributes.getNumAttrSets() > static_cast<unsigned>(1 + sig.sret)) {
AttrBuilder toShift;
for (auto it = attributes.index_begin() + 1 + sig.sret; it != attributes.index_end(); ++it) {
AttrBuilder toShiftTemp(attributes.getAttributes(it));
attributes = attributes.removeAttributes(jl_LLVMContext, it);
attributes = attributes.addAttributes(jl_LLVMContext, it, toShift);
toShift = std::move(toShiftTemp);
}
attributes = attributes.addAttributes(jl_LLVMContext, attributes.index_end(), toShift);
}

functype = FunctionType::get(sig.sret ? T_void : sig.prt, fargt_sig, /*isVa*/false);
attributes = attributes.addAttribute(jl_LLVMContext, 1 + sig.sret, Attribute::Nest);
}
else {
functype = sig.functype();
Expand Down
20 changes: 20 additions & 0 deletions test/ccall.jl
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,26 @@ for (t, v) in ((Complex{Int32}, :ci32), (Complex{Int64}, :ci64),
end
end


#issue 40164
@testset "llvm parameter attributes on cfunction closures" begin
struct Struct40164
x::Cdouble
y::Cdouble
z::Cdouble
end

function test_40164()
ret = Struct40164[]
f = x::Struct40164 -> (push!(ret, x); nothing)
f_c = @cfunction($f, Cvoid, (Struct40164,))
ccall(f_c.ptr, Ptr{Cvoid}, (Struct40164,), Struct40164(0, 1, 2))
ret
end

@test test_40164() == [Struct40164(0, 1, 2)]
end

else

@test_broken "cfunction: no support for closures on this platform"
Expand Down

0 comments on commit cae5325

Please sign in to comment.