Skip to content

Commit 983d71c

Browse files
committed
Parameter attributes on Cfunction closures sticks
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.
1 parent 0e8bb95 commit 983d71c

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

src/codegen.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5169,7 +5169,24 @@ static Function* gen_cfun_wrapper(
51695169
// add nest parameter (pointer to jl_value_t* data array) after sret arg
51705170
assert(closure_types);
51715171
std::vector<Type*> fargt_sig(sig.fargt_sig);
5172+
51725173
fargt_sig.insert(fargt_sig.begin() + sig.sret, T_pprjlvalue);
5174+
// Shift LLVM attributes for parameters one to the right, as
5175+
// we are adding the extra nest parameter after sret arg.
5176+
// AttributeList has Function attributes and return value
5177+
// attributes before the parameter attributes.
5178+
if (attributes.getNumAttrSets() > static_cast<unsigned>(2 + sig.sret)) {
5179+
AttrBuilder toShift;
5180+
// Skip past function and return and sret attributes to the first real parameter
5181+
for (auto it = attributes.index_begin() + 2 + sig.sret; it != attributes.index_end(); ++it) {
5182+
AttrBuilder toShiftTemp(attributes.getAttributes(it));
5183+
attributes = attributes.removeAttributes(jl_LLVMContext, it);
5184+
attributes = attributes.addAttributes(jl_LLVMContext, it, toShift);
5185+
toShift = std::move(toShiftTemp);
5186+
}
5187+
attributes = attributes.addAttributes(jl_LLVMContext, attributes.index_end(), toShift);
5188+
}
5189+
51735190
functype = FunctionType::get(sig.sret ? T_void : sig.prt, fargt_sig, /*isVa*/false);
51745191
attributes = attributes.addAttribute(jl_LLVMContext, 1 + sig.sret, Attribute::Nest);
51755192
}

test/ccall.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,26 @@ for (t, v) in ((Complex{Int32}, :ci32), (Complex{Int64}, :ci64),
982982
end
983983
end
984984

985+
986+
#issue 40164
987+
@testset "llvm parameter attributes on cfunction closures" begin
988+
struct Struct40164
989+
x::Cdouble
990+
y::Cdouble
991+
z::Cdouble
992+
end
993+
994+
function test_40164()
995+
ret = Struct40164[]
996+
f = x::Struct40164 -> (push!(ret, x); nothing)
997+
f_c = @cfunction($f, Cvoid, (Struct40164,))
998+
ccall(f_c.ptr, Ptr{Cvoid}, (Struct40164,), Struct40164(0, 1, 2))
999+
ret
1000+
end
1001+
1002+
@test test_40164() == [Struct40164(0, 1, 2)]
1003+
end
1004+
9851005
else
9861006

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

0 commit comments

Comments
 (0)