Skip to content

Commit

Permalink
fix #15489, don't check conversions during mixed signedness arithmetic
Browse files Browse the repository at this point in the history
also skip checks for integer bitwise ops
  • Loading branch information
JeffBezanson committed Oct 10, 2017
1 parent 10d470d commit 8dd77bd
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 5 deletions.
2 changes: 1 addition & 1 deletion base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ end
endof(v::SimpleVector) = length(v)
start(v::SimpleVector) = 1
next(v::SimpleVector,i) = (v[i],i+1)
done(v::SimpleVector,i) = (i > length(v))
done(v::SimpleVector,i) = (length(v) < i)
isempty(v::SimpleVector) = (length(v) == 0)
indices(v::SimpleVector) = (OneTo(length(v)),)
linearindices(v::SimpleVector) = indices(v, 1)
Expand Down
9 changes: 9 additions & 0 deletions base/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ if module_name(@__MODULE__) === :Base
end

rem(x::T, ::Type{T}) where {T<:Integer} = x
rem(x::Integer, T::Type{<:Integer}) = convert(T, x) # `x % T` falls back to `convert`
rem(x::Integer, ::Type{Bool}) = ((x & 1) != 0)
mod(x::Integer, ::Type{T}) where {T<:Integer} = rem(x, T)

Expand Down Expand Up @@ -767,3 +768,11 @@ else
rem(x::Int128, y::Int128) = checked_srem_int(x, y)
rem(x::UInt128, y::UInt128) = checked_urem_int(x, y)
end

# issue #15489: since integer ops are unchecked, they shouldn't check promotion
for op in (:+, :-, :*, :&, :|, :xor)
@eval function $op(a::Integer, b::Integer)
T = promote_typeof(a, b)
return $op(a % T, b % T)
end
end
4 changes: 0 additions & 4 deletions base/promotion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,6 @@ julia> A^3
fma(x::Number, y::Number, z::Number) = fma(promote(x,y,z)...)
muladd(x::Number, y::Number, z::Number) = muladd(promote(x,y,z)...)

(&)(x::Integer, y::Integer) = (&)(promote(x,y)...)
(|)(x::Integer, y::Integer) = (|)(promote(x,y)...)
xor(x::Integer, y::Integer) = xor(promote(x,y)...)

==(x::Number, y::Number) = (==)(promote(x,y)...)
<( x::Real, y::Real) = (< )(promote(x,y)...)
<=(x::Real, y::Real) = (<=)(promote(x,y)...)
Expand Down
8 changes: 8 additions & 0 deletions test/int.jl
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,14 @@ for T in [Base.BitInteger_types..., BigInt],
@test typeof(rand(U(0):U(127)) % T) === T
end

# issue #15489
@test 0x00007ffea27edaa0 + (-40) === (-40) + 0x00007ffea27edaa0 === 0x00007ffea27eda78
@test UInt64(1) * Int64(-1) === typemax(UInt64)
@test UInt(1) - (-1) == 2
@test UInt64(15) & -4 === UInt64(12)
@test UInt64(15) | -4 === typemax(UInt64)
@test UInt64(15) -4 === 0xfffffffffffffff3


@testset "left shift with Vector{Int} on BigInt-scalar #13832" begin
x = BigInt(1) .<< [1:70;]
Expand Down

0 comments on commit 8dd77bd

Please sign in to comment.