From 3ed3f43c7e6cb23d33743302783656a46e5c046a Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Fri, 22 Sep 2017 15:12:26 -0400 Subject: [PATCH] fix #15489, don't check conversions during mixed signedness arithmetic also skip checks for integer bitwise ops --- base/essentials.jl | 2 +- base/int.jl | 9 +++++++++ base/promotion.jl | 4 ---- test/int.jl | 8 ++++++++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/base/essentials.jl b/base/essentials.jl index 04d49dcef2e15..8223baa7fb31c 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -526,7 +526,7 @@ length(v::SimpleVector) = (@_noinline_meta; unsafe_load(convert(Ptr{Int},data_po 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) diff --git a/base/int.jl b/base/int.jl index e563dcc066df8..d521399a07544 100644 --- a/base/int.jl +++ b/base/int.jl @@ -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) @@ -770,3 +771,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 diff --git a/base/promotion.jl b/base/promotion.jl index 928f8a38808f4..3402cb836ab22 100644 --- a/base/promotion.jl +++ b/base/promotion.jl @@ -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)...) diff --git a/test/int.jl b/test/int.jl index 29ee29c7f00b1..b07f7e6c3b068 100644 --- a/test/int.jl +++ b/test/int.jl @@ -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;]