diff --git a/base/range.jl b/base/range.jl index f0bcc0dd20ae8..e82aa341db108 100644 --- a/base/range.jl +++ b/base/range.jl @@ -934,12 +934,16 @@ end function getindex(v::AbstractRange{T}, i::Integer) where T @inline i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) - ret = convert(T, first(v) + (i - oneunit(i))*step_hp(v)) - ok = ifelse(step(v) > zero(step(v)), - (ret <= last(v)) & (ret >= first(v)), - (ret <= first(v)) & (ret >= last(v))) - @boundscheck ((i > 0) & ok) || throw_boundserror(v, i) - ret + @boundscheck checkbounds(v, i) + convert(T, first(v) + (i - oneunit(i))*step_hp(v)) +end + +let BitInteger64 = Union{Int8,Int16,Int32,Int64,UInt8,UInt16,UInt32,UInt64} # for bootstrapping + function checkbounds(::Type{Bool}, v::StepRange{<:BitInteger64, <:BitInteger64}, i::BitInteger64) + @inline + res = widemul(step(v), i-oneunit(i)) + first(v) + (0 < i) & ifelse(0 < step(v), res <= last(v), res >= last(v)) + end end function getindex(r::Union{StepRangeLen,LinRange}, i::Integer) diff --git a/test/ranges.jl b/test/ranges.jl index 98233267d03a9..2e91e1ddbe078 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -2487,3 +2487,11 @@ function check_ranges(rx, ry) end @test Core.Compiler.is_foldable(Base.infer_effects(check_ranges, (UnitRange{Int},UnitRange{Int}))) # TODO JET.@test_opt check_ranges(1:2, 3:4) + +@testset "checkbounds overflow (#26623)" begin + # the reported issue: + @test_throws BoundsError (1:3:4)[typemax(Int)÷3*2+3] + + # a case that using mul_with_overflow & add_with_overflow might get wrong: + @test (-10:2:typemax(Int))[typemax(Int)÷2+2] == typemax(Int)-9 +end