diff --git a/src/abi_aarch64.cpp b/src/abi_aarch64.cpp index 3015cc3fb18e3..5b87548a50f9f 100644 --- a/src/abi_aarch64.cpp +++ b/src/abi_aarch64.cpp @@ -356,7 +356,8 @@ static Type *classify_arg(jl_value_t *ty, bool *fpreg, bool *onstack, bool use_sret(AbiState*, jl_value_t *ty) { - // Assume jl_is_datatype(ty) && !jl_is_abstracttype(ty) + // Assume (jl_is_datatype(ty) && !jl_is_abstracttype(ty) && + // !jl_is_array_type(ty)) // Section 5.5 // If the type, T, of the result of a function is such that // @@ -375,7 +376,7 @@ bool use_sret(AbiState*, jl_value_t *ty) Type *preferred_llvm_type(jl_value_t *ty, bool) { - if (!jl_is_datatype(ty) || jl_is_abstracttype(ty)) + if (!jl_is_datatype(ty) || jl_is_abstracttype(ty) || jl_is_array_type(ty)) return NULL; jl_datatype_t *dt = (jl_datatype_t*)ty; if (Type *fptype = get_llvm_fp_or_vectype(dt)) diff --git a/src/abi_arm.cpp b/src/abi_arm.cpp index 65a4dd188559e..acadd5c901ef4 100644 --- a/src/abi_arm.cpp +++ b/src/abi_arm.cpp @@ -206,7 +206,8 @@ static void classify_return_arg(jl_value_t *ty, bool *reg, bool use_sret(AbiState *state, jl_value_t *ty) { - // Assume jl_is_datatype(ty) && !jl_is_abstracttype(ty) + // Assume (jl_is_datatype(ty) && !jl_is_abstracttype(ty) && + // !jl_is_array_type(ty)) bool reg = false; bool onstack = false; @@ -254,7 +255,7 @@ static void classify_arg(jl_value_t *ty, bool *reg, Type *preferred_llvm_type(jl_value_t *ty, bool isret) { - if (!jl_is_datatype(ty) || jl_is_abstracttype(ty)) + if (!jl_is_datatype(ty) || jl_is_abstracttype(ty) || jl_is_array_type(ty)) return NULL; jl_datatype_t *dt = (jl_datatype_t*)ty; diff --git a/src/abi_win64.cpp b/src/abi_win64.cpp index 9ecf8cd3e68e9..3e8c441e79351 100644 --- a/src/abi_win64.cpp +++ b/src/abi_win64.cpp @@ -46,7 +46,9 @@ const AbiState default_abi_state = {}; bool use_sret(AbiState *state, jl_value_t *ty) { - if(!jl_is_datatype(ty) || jl_is_abstracttype(ty) || jl_is_cpointer_type(ty) || jl_is_array_type(ty)) + // Assume (jl_is_datatype(ty) && !jl_is_abstracttype(ty) && + // !jl_is_array_type(ty)) + if (jl_is_cpointer_type(ty)) return false; size_t size = jl_datatype_size(ty); if (size <= 8 || is_native_simd_type(ty)) diff --git a/src/abi_x86.cpp b/src/abi_x86.cpp index 4e345e20ab7cf..8b5d34304f8b3 100644 --- a/src/abi_x86.cpp +++ b/src/abi_x86.cpp @@ -56,7 +56,9 @@ inline bool is_complex128(jl_value_t *ty) bool use_sret(AbiState *state, jl_value_t *ty) { - if (!jl_is_datatype(ty) || jl_is_abstracttype(ty) || jl_is_cpointer_type(ty) || jl_is_array_type(ty)) + // Assume (jl_is_datatype(ty) && !jl_is_abstracttype(ty) && + // !jl_is_array_type(ty)) + if (jl_is_cpointer_type(ty)) return false; size_t size = jl_datatype_size(ty); if (size == 0) diff --git a/src/ccall.cpp b/src/ccall.cpp index d7db816a56046..322a23d0bdb8e 100644 --- a/src/ccall.cpp +++ b/src/ccall.cpp @@ -892,7 +892,8 @@ static std::string generate_func_sig( if (*prt == NULL) *prt = *lrt; - if (jl_is_datatype(rt) && !jl_is_abstracttype(rt) && use_sret(&abi, rt)) { + if (jl_is_datatype(rt) && !jl_is_abstracttype(rt) && + !jl_is_array_type(rt) && use_sret(&abi, rt)) { paramattrs.push_back(AttrBuilder()); paramattrs[0].clear(); #if !defined(_OS_WINDOWS_) || defined(LLVM35) // llvm used to use the old mingw ABI, skipping this marking works around that difference diff --git a/test/ccall.jl b/test/ccall.jl index 20e7245f880c5..0129954c87bb5 100644 --- a/test/ccall.jl +++ b/test/ccall.jl @@ -849,3 +849,14 @@ else warn("ccall: no VecReg tests run for this platform") end + +# Special calling convention for `Array` +function f17204(a) + b = similar(a) + for i in eachindex(a) + b[i] = a[i] + 10 + end + return b +end +@test ccall(cfunction(f17204, Vector{Any}, Tuple{Vector{Any}}), + Vector{Any}, (Vector{Any},), Any[1:10;]) == Any[11:20;]