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

[Release-0.6] Fix missing bounds checks for trailing zero dimensions #23723

Merged
merged 1 commit into from
Sep 18, 2017
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
5 changes: 3 additions & 2 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -407,9 +407,10 @@ function checkbounds_indices(::Type{Bool}, IA::Tuple, I::Tuple{Any})
end
function checkbounds_linear_indices(::Type{Bool}, IA::Tuple{Vararg{OneTo}}, i)
@_inline_meta
if checkindex(Bool, IA[1], i)
ts = trailingsize(IA)
if checkindex(Bool, IA[1], i) && ts > 0
return true
elseif checkindex(Bool, OneTo(trailingsize(IA)), i) # partial linear indexing
elseif checkindex(Bool, OneTo(ts), i) # partial linear indexing
partial_linear_indexing_warning_lookup(length(IA))
return true # TODO: Return false after the above function is removed in deprecated.jl
end
Expand Down
13 changes: 10 additions & 3 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1726,17 +1726,24 @@ static Value *emit_array_nd_index(const jl_cgval_t &ainfo, jl_value_t *ex, ssize
// the accessed array, i.e. `if !(i < alen) goto error`.
if (nidxs > 1) {
// TODO: REMOVE DEPWARN AND RETURN FALSE AFTER 0.6.
// We need to check if this is inside the non-linearized size
// We need to check if this index is inside its non-linearized dimension
BasicBlock *partidx = BasicBlock::Create(jl_LLVMContext, "partlinidx");
BasicBlock *partidxwarn = BasicBlock::Create(jl_LLVMContext, "partlinidxwarn");
BasicBlock *trailingcheck = BasicBlock::Create(jl_LLVMContext, "trailingcheck");
Value *d = emit_arraysize_for_unsafe_dim(ainfo, ex, nidxs, nd, ctx);
builder.CreateCondBr(builder.CreateICmpULT(ii, d), endBB, partidx);
Value *alen = emit_arraylen(ainfo, ex, ctx);
builder.CreateCondBr(builder.CreateICmpULT(ii, d), trailingcheck, partidx);

// If it is inside its own dimension, we still need to ensure all other
// dimensions are non-zero
ctx->f->getBasicBlockList().push_back(trailingcheck);
builder.SetInsertPoint(trailingcheck);
builder.CreateCondBr(builder.CreateICmpULT(ii, alen), endBB, failBB);

// We failed the normal bounds check; check to see if we're
// inside the linearized size (partial linear indexing):
ctx->f->getBasicBlockList().push_back(partidx);
builder.SetInsertPoint(partidx);
Value *alen = emit_arraylen(ainfo, ex, ctx);
builder.CreateCondBr(builder.CreateICmpULT(i, alen), partidxwarn, failBB);

// We passed the linearized bounds check; now throw the depwarn:
Expand Down
5 changes: 5 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2104,3 +2104,8 @@ Base.:(==)(a::T11053, b::T11053) = a.a == b.a

#15907
@test typeof(Array{Int,0}()) == Array{Int,0}

@testset "issue 23629" begin
@test_throws BoundsError zeros(2,3,0)[2,3]
@test_throws BoundsError checkbounds(zeros(2,3,0), 2, 3)
end