diff --git a/src/ccall.cpp b/src/ccall.cpp index 48fb46266cf91..6fda7f4ea8427 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -1777,19 +1777,20 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) JL_GC_POP(); return mark_or_box_ccall_result(ctx, strp, retboxed, rt, unionall, static_rt); } - else if (is_libjulia_func(memcpy)) { + else if (is_libjulia_func(memcpy) && (rt == (jl_value_t*)jl_void_type || jl_is_cpointer_type(rt))) { const jl_cgval_t &dst = argv[0]; const jl_cgval_t &src = argv[1]; const jl_cgval_t &n = argv[2]; + Value *destp = emit_unbox(ctx, T_size, dst, (jl_value_t*)jl_voidpointer_type); ctx.builder.CreateMemCpy( - ctx.builder.CreateIntToPtr( - emit_unbox(ctx, T_size, dst, (jl_value_t*)jl_voidpointer_type), T_pint8), + ctx.builder.CreateIntToPtr(destp, T_pint8), ctx.builder.CreateIntToPtr( emit_unbox(ctx, T_size, src, (jl_value_t*)jl_voidpointer_type), T_pint8), emit_unbox(ctx, T_size, n, (jl_value_t*)jl_ulong_type), 1, false); JL_GC_POP(); - return ghostValue(jl_void_type); + return rt == (jl_value_t*)jl_void_type ? ghostValue(jl_void_type) : + mark_or_box_ccall_result(ctx, destp, retboxed, rt, unionall, static_rt); } jl_cgval_t retval = sig.emit_a_ccall( diff --git a/test/ccall.jl b/test/ccall.jl index 54a6ebe4d497d..28b072f351edf 100644 --- a/test/ccall.jl +++ b/test/ccall.jl @@ -1477,3 +1477,16 @@ test27477() = ccall((:ctest, Pkg27477.libccalltest), Complex{Int}, (Complex{Int} end @test Test27477.test27477() == 2 + 0im + +# issue #31073 +let + a = ['0'] + arr = Vector{Char}(undef, 2) + ptr = pointer(arr) + elsz = sizeof(Char) + na = length(a) + nba = na * elsz + ptr = eval(:(ccall(:memcpy, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, UInt), $(arr), $(a), $(nba)))) + @test isa(ptr, Ptr{Cvoid}) + @test arr[1] == '0' +end