Skip to content

Commit

Permalink
Test functionality of automatic conversion in ccall
Browse files Browse the repository at this point in the history
This adds tests for the `cconvert` method used implicitly during
`ccall`s. When designing the tests, though, it became obvious that
real-world conversion to `Cint` arguments (such as calls to `mmap`
in UnixMmap.jl) weren't covered by the existing method.

Change the behavior to allow for conversion to any integer type which
can be represented by the destination type.
  • Loading branch information
jmert committed Nov 11, 2022
1 parent 2378d5d commit 16ba320
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/BitFlags.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ abstract type BitFlag{T<:Integer} end

basetype(::Type{<:BitFlag{T}}) where {T<:Integer} = T

(::Type{T})(x::BitFlag{T2}) where {T<:Integer,T2<:Unsigned} = T(bitcast(T2, x))::T
Base.cconvert(::Type{T}, x::BitFlag{T2}) where {T<:Unsigned,T2<:Unsigned} = T(x)
Base.write(io::IO, x::BitFlag{T}) where {T<:Unsigned} = write(io, T(x))
(::Type{T})(x::BitFlag{T2}) where {T<:Integer, T2} = T(bitcast(T2, x))::T
Base.cconvert(::Type{T}, x::BitFlag{T2}) where {T<:Integer, T2} = T(T2(x))
Base.write(io::IO, x::BitFlag{T}) where {T} = write(io, T(x))
Base.read(io::IO, ::Type{T}) where {T<:BitFlag} = T(read(io, basetype(T)))

Base.isless(x::T, y::T) where {T<:BitFlag} = isless(basetype(T)(x), basetype(T)(y))
Expand Down
16 changes: 16 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ end

# Broadcasting
@test [flag1a, flag1b] .| flag1c == [flag1a | flag1c, flag1b | flag1c]

# ccall conversion
@bitflag CFlag1::UInt64 begin
cflag1_small = 1
cflag1_large = UInt64(1) << 63
end
flag_nonzero(x::Integer) = Cint(!iszero(x))
cflag_nonzero_u64 = @cfunction(flag_nonzero, Cint, (UInt64,))
cflag_nonzero_u32 = @cfunction(flag_nonzero, Cint, (UInt32,))
cflag_nonzero_i32 = @cfunction(flag_nonzero, Cint, (Int32,))
@test ccall(cflag_nonzero_u64, Cint, (UInt64,), cflag1_small) == 1
@test ccall(cflag_nonzero_u32, Cint, (UInt32,), cflag1_small) == 1
@test ccall(cflag_nonzero_i32, Cint, (Int32,), cflag1_small) == 1
@test ccall(cflag_nonzero_u64, Cint, (UInt64,), cflag1_large) == 1
@test_throws InexactError ccall(cflag_nonzero_u32, Cint, (UInt32,), cflag1_large)
@test_throws InexactError ccall(cflag_nonzero_i32, Cint, (Int32,), cflag1_large)
#end

#@testset "Type properties" begin
Expand Down

0 comments on commit 16ba320

Please sign in to comment.