Skip to content

Commit

Permalink
Fix missing bounds checks for trailing zero dimensions (#23723)
Browse files Browse the repository at this point in the history
This fixes issue #23629 for 0.6. It is done independently from the fix for master (in #23628) due to all the deprecation changes.
  • Loading branch information
mbauman authored and ararslan committed Sep 18, 2017
1 parent 7c2e296 commit 4cc3b41
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
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 @@ -2119,3 +2119,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

0 comments on commit 4cc3b41

Please sign in to comment.