From a8cd1f7fd7f40a79a7da58e864ba9aff12a28173 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Mon, 7 Aug 2023 16:52:17 -0300 Subject: [PATCH] Make ranges more robust with unsigned indexes. --- base/range.jl | 18 ++++++++++++++---- base/twiceprecision.jl | 12 ++++++++++-- test/ranges.jl | 5 +++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/base/range.jl b/base/range.jl index e8ffe10e2ba7f..ac4bbf28e2de1 100644 --- a/base/range.jl +++ b/base/range.jl @@ -963,14 +963,24 @@ end # This is separate to make it useful even when running with --check-bounds=yes function unsafe_getindex(r::StepRangeLen{T}, i::Integer) where T i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) - u = i - r.offset - T(r.ref + u*r.step) + if i < r.offset # 1 <= offset <= len && 1 <= i <= len + u = r.offset - i + return T(r.ref - u*r.step) + else + u = i - r.offset + return T(r.ref + u*r.step) + end end function _getindex_hiprec(r::StepRangeLen, i::Integer) # without rounding by T i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) - u = i - r.offset - r.ref + u*r.step + if i < r.offset # 1 <= offset <= len && 1 <= i <= len + u = r.offset - i + return r.ref - u*r.step + else + u = i - r.offset + return r.ref + u*r.step + end end function unsafe_getindex(r::LinRange, i::Integer) diff --git a/base/twiceprecision.jl b/base/twiceprecision.jl index d91a04371230c..24b10afb033af 100644 --- a/base/twiceprecision.jl +++ b/base/twiceprecision.jl @@ -478,7 +478,11 @@ function unsafe_getindex(r::StepRangeLen{T,<:TwicePrecision,<:TwicePrecision}, i # Very similar to _getindex_hiprec, but optimized to avoid a 2nd call to add12 @inline i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) - u = i - r.offset + if i < r.offset # 1 <= offset <= len && 1 <= i <= len + u = r.offset - i + else + u = i - r.offset + end shift_hi, shift_lo = u*r.step.hi, u*r.step.lo x_hi, x_lo = add12(r.ref.hi, shift_hi) T(x_hi + (x_lo + (shift_lo + r.ref.lo))) @@ -486,7 +490,11 @@ end function _getindex_hiprec(r::StepRangeLen{<:Any,<:TwicePrecision,<:TwicePrecision}, i::Integer) i isa Bool && throw(ArgumentError("invalid index: $i of type Bool")) - u = i - r.offset + if i < r.offset # 1 <= offset <= len && 1 <= i <= len + u = r.offset - i + else + u = i - r.offset + end shift_hi, shift_lo = u*r.step.hi, u*r.step.lo x_hi, x_lo = add12(r.ref.hi, shift_hi) x_hi, x_lo = add12(x_hi, x_lo + (shift_lo + r.ref.lo)) diff --git a/test/ranges.jl b/test/ranges.jl index 137f9c885da26..05a09fa5c8730 100644 --- a/test/ranges.jl +++ b/test/ranges.jl @@ -2528,3 +2528,8 @@ end end end + +@testset "unsigned index #44895" begin + x = range(-1,1,length=11) + x[UInt(1)] == 1.0 +end \ No newline at end of file