Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ranges more robust with unsigned indexes. #50823

Merged
merged 2 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions base/range.jl
Original file line number Diff line number Diff line change
Expand Up @@ -963,13 +963,13 @@ 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
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if a better fix would be

    u = oftype(r.offset, i) - r.offset

since if the number wasn't representable as the type of the offset, then it was out of bounds anyways. and this cast should typically be free.

u = oftype(r.offset, i) - r.offset
T(r.ref + u*r.step)
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
u = oftype(r.offset, i) - r.offset
r.ref + u*r.step
end

Expand Down
4 changes: 2 additions & 2 deletions base/twiceprecision.jl
Original file line number Diff line number Diff line change
Expand Up @@ -478,15 +478,15 @@ 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
u = oftype(r.offset, i) - r.offset
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)))
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
u = oftype(r.offset, i) - r.offset
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))
Expand Down
7 changes: 7 additions & 0 deletions test/ranges.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2528,3 +2528,10 @@ end
end

end

@testset "unsigned index #44895" begin
x = range(-1,1,length=11)
@test x[UInt(1)] == -1.0
a = StepRangeLen(1,2,3,2)
@test a[UInt(1)] == -1
end
4 changes: 2 additions & 2 deletions test/testhelpers/OffsetArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ end
@inline function Base.getindex(r::IdOffsetRange, i::Integer)
i isa Bool && throw(ArgumentError("invalid index: $i of type Bool"))
@boundscheck checkbounds(r, i)
@inbounds eltype(r)(r.parent[i - r.offset] + r.offset)
@inbounds eltype(r)(r.parent[oftype(r.offset, i) - r.offset] + r.offset)
end

# Logical indexing following https://github.com/JuliaLang/julia/pull/31829
Expand Down Expand Up @@ -592,7 +592,7 @@ Base.fill!(A::OffsetArray, x) = parent_call(Ap -> fill!(Ap, x), A)
# Δi = i - first(r)
# i′ = first(r.parent) + Δi
# and one obtains the result below.
parentindex(r::IdOffsetRange, i) = i - r.offset
parentindex(r::IdOffsetRange, i) = oftype(r.offset, i) - r.offset

@propagate_inbounds Base.getindex(A::OffsetArray{<:Any,0}) = A.parent[]

Expand Down