Skip to content

Commit ccd36a8

Browse files
committed
Accept both Cvoid and Ptr{Void} return type in ccall(:memcpy)
POSIX specifies that memcpy returns its first argument, which is a bit of a useless feature (e.g. the llvm intrinsic just returns `void`. Nevertheless, since we're intercepting the ccall here, we should allow it. For convenience, still allow the Cvoid return though. Fixes #31073
1 parent 672bf8b commit ccd36a8

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

src/ccall.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,19 +1777,20 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
17771777
JL_GC_POP();
17781778
return mark_or_box_ccall_result(ctx, strp, retboxed, rt, unionall, static_rt);
17791779
}
1780-
else if (is_libjulia_func(memcpy)) {
1780+
else if (is_libjulia_func(memcpy) && (rt == (jl_value_t*)jl_void_type || jl_is_cpointer_type(rt))) {
17811781
const jl_cgval_t &dst = argv[0];
17821782
const jl_cgval_t &src = argv[1];
17831783
const jl_cgval_t &n = argv[2];
1784+
Value *destp = emit_unbox(ctx, T_size, dst, (jl_value_t*)jl_voidpointer_type);
17841785
ctx.builder.CreateMemCpy(
1785-
ctx.builder.CreateIntToPtr(
1786-
emit_unbox(ctx, T_size, dst, (jl_value_t*)jl_voidpointer_type), T_pint8),
1786+
ctx.builder.CreateIntToPtr(destp, T_pint8),
17871787
ctx.builder.CreateIntToPtr(
17881788
emit_unbox(ctx, T_size, src, (jl_value_t*)jl_voidpointer_type), T_pint8),
17891789
emit_unbox(ctx, T_size, n, (jl_value_t*)jl_ulong_type), 1,
17901790
false);
17911791
JL_GC_POP();
1792-
return ghostValue(jl_void_type);
1792+
return rt == (jl_value_t*)jl_void_type ? ghostValue(jl_void_type) :
1793+
mark_or_box_ccall_result(ctx, destp, retboxed, rt, unionall, static_rt);
17931794
}
17941795

17951796
jl_cgval_t retval = sig.emit_a_ccall(

test/ccall.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,3 +1477,16 @@ test27477() = ccall((:ctest, Pkg27477.libccalltest), Complex{Int}, (Complex{Int}
14771477
end
14781478

14791479
@test Test27477.test27477() == 2 + 0im
1480+
1481+
# issue #31073
1482+
let
1483+
a = ['0']
1484+
arr = Vector{Char}(undef, 2)
1485+
ptr = pointer(arr)
1486+
elsz = sizeof(Char)
1487+
na = length(a)
1488+
nba = na * elsz
1489+
ptr = eval(:(ccall(:memcpy, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, UInt), $(arr), $(a), $(nba))))
1490+
@test isa(ptr, Ptr{Cvoid})
1491+
@test arr[1] == '0'
1492+
end

0 commit comments

Comments
 (0)