diff --git a/NEWS.md b/NEWS.md index 7ef91ecf65efe..c6462b408de58 100644 --- a/NEWS.md +++ b/NEWS.md @@ -34,6 +34,10 @@ New language features Library improvements -------------------- + * `convert(Ptr{T1}, x::Array{T2})` is now deprecated unless `T1 == T2` + or `T1 == None` ([#6073]). (You can still explicitly `convert` + one pointer type into another if needed.) + * Well-behaved floating-point ranges ([#2333], [#5636]). Introduced the `FloatRange` type for floating-point ranges with a step, which will give intuitive/correct results for classically problematic diff --git a/base/deprecated.jl b/base/deprecated.jl index ed39c6229bd11..a2165ab4dc88c 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -12,9 +12,16 @@ macro deprecate(old,new) elseif isa(old,Expr) && old.head == :call oldcall = sprint(io->show_unquoted(io,old)) newcall = sprint(io->show_unquoted(io,new)) - oldname = Expr(:quote, old.args[1]) + oldsym = if isa(old.args[1],Symbol) + old.args[1] + elseif isa(old.args[1],Expr) && old.args[1].head == :curly + old.args[1].args[1] + else + error("invalid usage of @deprecate") + end + oldname = Expr(:quote, oldsym) Expr(:toplevel, - Expr(:export,esc(old.args[1])), + Expr(:export,esc(oldsym)), :($(esc(old)) = begin depwarn(string($oldcall," is deprecated, use ",$newcall," instead."), $oldname) @@ -402,6 +409,8 @@ Set{T<:Number}(xs::T...) = Set{T}(xs) @deprecate normfro(A) vecnorm(A) +@deprecate convert{T}(p::Type{Ptr{T}}, a::Array) convert(p, pointer(a)) + # 0.3 discontinued functions function nnz(X) diff --git a/base/linalg/cholmod.jl b/base/linalg/cholmod.jl index ce797bd5989b0..5dcc61dfeae1e 100644 --- a/base/linalg/cholmod.jl +++ b/base/linalg/cholmod.jl @@ -86,7 +86,7 @@ end ### These offsets should be reconfigured to be less error-prone in matches const chm_com_offsets = Array(Int, length(ChmCommon.types)) ccall((:jl_cholmod_common_offsets, :libsuitesparse_wrapper), - Void, (Ptr{Uint8},), chm_com_offsets) + Void, (Ptr{Int},), chm_com_offsets) const chm_final_ll_inds = (1:4) + chm_com_offsets[7] const chm_prt_inds = (1:4) + chm_com_offsets[13] const chm_ityp_inds = (1:4) + chm_com_offsets[18] diff --git a/base/linalg/lapack.jl b/base/linalg/lapack.jl index 1a542f17b5111..5f5d4653b53ed 100644 --- a/base/linalg/lapack.jl +++ b/base/linalg/lapack.jl @@ -1027,7 +1027,7 @@ for (geev, gesvd, gesdd, ggsvd, elty, relty) in if cmplx ccall(($(string(gesdd)),liblapack), Void, (Ptr{BlasChar}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{$elty}, - Ptr{BlasInt}, Ptr{$elty}, Ptr{$elty}, Ptr{BlasInt}, + Ptr{BlasInt}, Ptr{$relty}, Ptr{$elty}, Ptr{BlasInt}, Ptr{$elty}, Ptr{BlasInt}, Ptr{$elty}, Ptr{BlasInt}, Ptr{$relty}, Ptr{BlasInt}, Ptr{BlasInt}), &job, &m, &n, A, &max(1,stride(A,2)), S, U, &max(1,stride(U,2)), VT, &max(1,stride(VT,2)), @@ -2070,7 +2070,7 @@ for (trcon, trevc, trrfs, elty, relty) in @chkuplo rcond = Array($relty, 1) work = Array($elty, 2n) - rwork = Array($elty, n) + rwork = Array($relty, n) info = Array(BlasInt, 1) ccall(($(string(trcon)),liblapack), Void, (Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasInt}, @@ -2150,7 +2150,7 @@ for (trcon, trevc, trrfs, elty, relty) in nrhs=size(B,2) nrhs==size(X,2) || throw(DimensionMismatch("")) work=Array($elty, 2n) - rwork=Array($elty, n) + rwork=Array($relty, n) info=Array(BlasInt, 1) ccall(($(string(trrfs)),liblapack), Void, (Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasInt}, @@ -2987,7 +2987,7 @@ for (syev, syevr, sygvd, elty, relty) in (Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasInt}, Ptr{$elty}, Ptr{BlasInt}, Ptr{$elty}, Ptr{$elty}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{$elty}, Ptr{BlasInt}, - Ptr{$elty}, Ptr{$elty}, Ptr{BlasInt}, Ptr{BlasInt}, + Ptr{$relty}, Ptr{$elty}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{$elty}, Ptr{BlasInt}, Ptr{$relty}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{BlasInt}), &jobz, &range, &uplo, &n, diff --git a/base/pointer.jl b/base/pointer.jl index 3e2debbaca24c..1c52dec7bb173 100644 --- a/base/pointer.jl +++ b/base/pointer.jl @@ -16,10 +16,12 @@ convert{T}(::Type{Ptr{T}}, p::Ptr) = box(Ptr{T}, unbox(Ptr,p)) # object to pointer convert(::Type{Ptr{Uint8}}, x::Symbol) = ccall(:jl_symbol_name, Ptr{Uint8}, (Any,), x) convert(::Type{Ptr{Int8}}, x::Symbol) = ccall(:jl_symbol_name, Ptr{Int8}, (Any,), x) -convert{T}(::Type{Ptr{T}}, a::Array) = ccall(:jl_array_ptr, Ptr{T}, (Any,), a) convert(::Type{Ptr{Uint8}}, s::ByteString) = convert(Ptr{Uint8}, s.data) convert(::Type{Ptr{Int8}}, s::ByteString) = convert(Ptr{Int8}, s.data) +convert{T}(::Type{Ptr{T}}, a::Array{T}) = ccall(:jl_array_ptr, Ptr{T}, (Any,), a) +convert(::Type{Ptr{None}}, a::Array) = ccall(:jl_array_ptr, Ptr{None}, (Any,), a) + pointer{T}(::Type{T}, x::Uint) = convert(Ptr{T}, x) pointer{T}(::Type{T}, x::Ptr) = convert(Ptr{T}, x) # note: these definitions don't mean any AbstractArray is convertible to diff --git a/doc/manual/calling-c-and-fortran-code.rst b/doc/manual/calling-c-and-fortran-code.rst index ff5cb1b494f1f..77664853f96f6 100644 --- a/doc/manual/calling-c-and-fortran-code.rst +++ b/doc/manual/calling-c-and-fortran-code.rst @@ -192,16 +192,20 @@ When a scalar value is passed with ``&`` as an argument of type Array conversions ~~~~~~~~~~~~~~~~~ -When an ``Array`` is passed to C as a ``Ptr`` argument, it is -"converted" simply by taking the address of the first element. This is -done in order to avoid copying arrays unnecessarily, and to tolerate the -slight mismatches in pointer types that are often encountered in C APIs -(for example, passing a ``Float64`` array to a function that operates on -uninterpreted bytes). +When an ``Array{T}`` is passed to C as a ``Ptr{T}`` or ``Ptr{Void}`` +argument, it is "converted" simply by taking the address of the first +element. This is done in order to avoid copying arrays unnecessarily. Therefore, if an ``Array`` contains data in the wrong format, it will have to be explicitly converted using a call such as ``int32(a)``. +To pass an array ``A`` as a pointer of a different type *without* +converting the data (for example, to pass a ``Float64`` array to a +function that operates on uninterpreted bytes), you can either declare +the argument as ``Ptr{Void}`` or you can explicitly call +``convert(Ptr{T}, pointer(A))``. + + Type correspondences ~~~~~~~~~~~~~~~~~~~~