From 8d2727ba5d1208db663b43216362356e4f96a160 Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Fri, 10 May 2019 15:41:59 +0200 Subject: [PATCH] Accept both Cvoid and Ptr{Void} return type in ccall(:memcpy) (#31464) 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 --- src/ccall.cpp | 12 ++++++------ test/ccall.jl | 13 +++++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/ccall.cpp b/src/ccall.cpp index 0e696ec647342..707aead0d9f7d 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -1691,15 +1691,15 @@ 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); #if JL_LLVM_VERSION >= 70000 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), 1, ctx.builder.CreateIntToPtr( emit_unbox(ctx, T_size, src, (jl_value_t*)jl_voidpointer_type), T_pint8), @@ -1708,15 +1708,15 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs) false); #else 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); #endif 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); } else if (is_libjulia_func(jl_object_id) && nargt == 1 && rt == (jl_value_t*)jl_ulong_type) { 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