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 10, 2021
1 parent 0e8bb95 commit 983d71c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5169,7 +5169,24 @@ 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);
// Shift LLVM attributes for parameters one to the right, as
// we are adding the extra nest parameter after sret arg.
// AttributeList has Function attributes and return value
// attributes before the parameter attributes.
if (attributes.getNumAttrSets() > static_cast<unsigned>(2 + sig.sret)) {
AttrBuilder toShift;
// Skip past function and return and sret attributes to the first real parameter
for (auto it = attributes.index_begin() + 2 + 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);
}
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 983d71c

Please sign in to comment.