Skip to content

Commit 16ba320

Browse files
committed
Test functionality of automatic conversion in ccall
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.
1 parent 2378d5d commit 16ba320

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

src/BitFlags.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ abstract type BitFlag{T<:Integer} end
1616

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

19-
(::Type{T})(x::BitFlag{T2}) where {T<:Integer,T2<:Unsigned} = T(bitcast(T2, x))::T
20-
Base.cconvert(::Type{T}, x::BitFlag{T2}) where {T<:Unsigned,T2<:Unsigned} = T(x)
21-
Base.write(io::IO, x::BitFlag{T}) where {T<:Unsigned} = write(io, T(x))
19+
(::Type{T})(x::BitFlag{T2}) where {T<:Integer, T2} = T(bitcast(T2, x))::T
20+
Base.cconvert(::Type{T}, x::BitFlag{T2}) where {T<:Integer, T2} = T(T2(x))
21+
Base.write(io::IO, x::BitFlag{T}) where {T} = write(io, T(x))
2222
Base.read(io::IO, ::Type{T}) where {T<:BitFlag} = T(read(io, basetype(T)))
2323

2424
Base.isless(x::T, y::T) where {T<:BitFlag} = isless(basetype(T)(x), basetype(T)(y))

test/runtests.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,22 @@ end
6969

7070
# Broadcasting
7171
@test [flag1a, flag1b] .| flag1c == [flag1a | flag1c, flag1b | flag1c]
72+
73+
# ccall conversion
74+
@bitflag CFlag1::UInt64 begin
75+
cflag1_small = 1
76+
cflag1_large = UInt64(1) << 63
77+
end
78+
flag_nonzero(x::Integer) = Cint(!iszero(x))
79+
cflag_nonzero_u64 = @cfunction(flag_nonzero, Cint, (UInt64,))
80+
cflag_nonzero_u32 = @cfunction(flag_nonzero, Cint, (UInt32,))
81+
cflag_nonzero_i32 = @cfunction(flag_nonzero, Cint, (Int32,))
82+
@test ccall(cflag_nonzero_u64, Cint, (UInt64,), cflag1_small) == 1
83+
@test ccall(cflag_nonzero_u32, Cint, (UInt32,), cflag1_small) == 1
84+
@test ccall(cflag_nonzero_i32, Cint, (Int32,), cflag1_small) == 1
85+
@test ccall(cflag_nonzero_u64, Cint, (UInt64,), cflag1_large) == 1
86+
@test_throws InexactError ccall(cflag_nonzero_u32, Cint, (UInt32,), cflag1_large)
87+
@test_throws InexactError ccall(cflag_nonzero_i32, Cint, (Int32,), cflag1_large)
7288
#end
7389

7490
#@testset "Type properties" begin

0 commit comments

Comments
 (0)