Skip to content

Commit a8cd1f7

Browse files
committed
Make ranges more robust with unsigned indexes.
1 parent 9f9e989 commit a8cd1f7

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

base/range.jl

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -963,14 +963,24 @@ end
963963
# This is separate to make it useful even when running with --check-bounds=yes
964964
function unsafe_getindex(r::StepRangeLen{T}, i::Integer) where T
965965
i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
966-
u = i - r.offset
967-
T(r.ref + u*r.step)
966+
if i < r.offset # 1 <= offset <= len && 1 <= i <= len
967+
u = r.offset - i
968+
return T(r.ref - u*r.step)
969+
else
970+
u = i - r.offset
971+
return T(r.ref + u*r.step)
972+
end
968973
end
969974

970975
function _getindex_hiprec(r::StepRangeLen, i::Integer) # without rounding by T
971976
i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
972-
u = i - r.offset
973-
r.ref + u*r.step
977+
if i < r.offset # 1 <= offset <= len && 1 <= i <= len
978+
u = r.offset - i
979+
return r.ref - u*r.step
980+
else
981+
u = i - r.offset
982+
return r.ref + u*r.step
983+
end
974984
end
975985

976986
function unsafe_getindex(r::LinRange, i::Integer)

base/twiceprecision.jl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,15 +478,23 @@ function unsafe_getindex(r::StepRangeLen{T,<:TwicePrecision,<:TwicePrecision}, i
478478
# Very similar to _getindex_hiprec, but optimized to avoid a 2nd call to add12
479479
@inline
480480
i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
481-
u = i - r.offset
481+
if i < r.offset # 1 <= offset <= len && 1 <= i <= len
482+
u = r.offset - i
483+
else
484+
u = i - r.offset
485+
end
482486
shift_hi, shift_lo = u*r.step.hi, u*r.step.lo
483487
x_hi, x_lo = add12(r.ref.hi, shift_hi)
484488
T(x_hi + (x_lo + (shift_lo + r.ref.lo)))
485489
end
486490

487491
function _getindex_hiprec(r::StepRangeLen{<:Any,<:TwicePrecision,<:TwicePrecision}, i::Integer)
488492
i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
489-
u = i - r.offset
493+
if i < r.offset # 1 <= offset <= len && 1 <= i <= len
494+
u = r.offset - i
495+
else
496+
u = i - r.offset
497+
end
490498
shift_hi, shift_lo = u*r.step.hi, u*r.step.lo
491499
x_hi, x_lo = add12(r.ref.hi, shift_hi)
492500
x_hi, x_lo = add12(x_hi, x_lo + (shift_lo + r.ref.lo))

test/ranges.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2528,3 +2528,8 @@ end
25282528
end
25292529

25302530
end
2531+
2532+
@testset "unsigned index #44895" begin
2533+
x = range(-1,1,length=11)
2534+
x[UInt(1)] == 1.0
2535+
end

0 commit comments

Comments
 (0)