Skip to content

Commit 372b3ff

Browse files
authored
Merge pull request #177 from maleadt/tb/bounds_checking
Add bounds checking to iterators.
2 parents 09eedb6 + ae69123 commit 372b3ff

File tree

6 files changed

+27
-12
lines changed

6 files changed

+27
-12
lines changed

src/core/function.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ parameters(f::Function) = FunctionParameterSet(f)
8484

8585
Base.eltype(::FunctionParameterSet) = Argument
8686

87-
Base.getindex(iter::FunctionParameterSet, i) =
88-
Argument(API.LLVMGetParam(ref(iter.f), i-1))
87+
function Base.getindex(iter::FunctionParameterSet, i)
88+
@boundscheck 1 <= i <= length(iter) || throw(BoundsError(iter, i))
89+
return Argument(API.LLVMGetParam(ref(iter.f), i-1))
90+
end
8991

9092
function Base.iterate(iter::FunctionParameterSet, state=API.LLVMGetFirstParam(ref(iter.f)))
9193
state == C_NULL ? nothing : (Argument(state), API.LLVMGetNextParam(state))

src/core/instructions.jl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,10 @@ successors(term::Instruction) = TerminatorSuccessorSet(term)
167167

168168
Base.eltype(::TerminatorSuccessorSet) = BasicBlock
169169

170-
Base.getindex(iter::TerminatorSuccessorSet, i) =
171-
BasicBlock(API.LLVMGetSuccessor(ref(iter.term), i-1))
170+
function Base.getindex(iter::TerminatorSuccessorSet, i)
171+
@boundscheck 1 <= i <= length(iter) || throw(BoundsError(iter, i))
172+
return BasicBlock(API.LLVMGetSuccessor(ref(iter.term), i-1))
173+
end
172174

173175
Base.setindex!(iter::TerminatorSuccessorSet, bb::BasicBlock, i) =
174176
API.LLVMSetSuccessor(ref(iter.term), i-1, blockref(bb))
@@ -196,9 +198,11 @@ incoming(phi::Instruction) = PhiIncomingSet(phi)
196198

197199
Base.eltype(::PhiIncomingSet) = Tuple{Value,BasicBlock}
198200

199-
Base.getindex(iter::PhiIncomingSet, i) =
200-
tuple(Value(API.LLVMGetIncomingValue(ref(iter.phi), i-1)),
201-
BasicBlock(API.LLVMGetIncomingBlock(ref(iter.phi), i-1)))
201+
function Base.getindex(iter::PhiIncomingSet, i)
202+
@boundscheck 1 <= i <= length(iter) || throw(BoundsError(iter, i))
203+
return tuple(Value(API.LLVMGetIncomingValue(ref(iter.phi), i-1)),
204+
BasicBlock(API.LLVMGetIncomingBlock(ref(iter.phi), i-1)))
205+
end
202206

203207
function Base.append!(iter::PhiIncomingSet, args::Vector{Tuple{V, BasicBlock}} where V <: Value)
204208
vals, blocks = zip(args...)

src/core/type.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,10 @@ elements(typ::StructType) = StructTypeElementSet(typ)
217217

218218
Base.eltype(::StructTypeElementSet) = LLVMType
219219

220-
Base.getindex(iter::StructTypeElementSet, i) =
221-
LLVMType(API.LLVMStructGetTypeAtIndex(ref(iter.typ), i-1))
220+
function Base.getindex(iter::StructTypeElementSet, i)
221+
@boundscheck 1 <= i <= length(iter) || throw(BoundsError(iter, i))
222+
return LLVMType(API.LLVMStructGetTypeAtIndex(ref(iter.typ), i-1))
223+
end
222224

223225
function Base.iterate(iter::StructTypeElementSet, i=1)
224226
i >= length(iter) + 1 ? nothing : (iter[i], i+1)

src/core/value/user.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ operands(user::User) = UserOperandSet(user)
1414

1515
Base.eltype(::UserOperandSet) = Value
1616

17-
Base.getindex(iter::UserOperandSet, i::Integer) = # TODO: otherwise unitrange indexing errors
18-
Value(API.LLVMGetOperand(ref(iter.user), i-1))
17+
function Base.getindex(iter::UserOperandSet, i::Integer) # TODO: otherwise unitrange indexing errors
18+
@boundscheck 1 <= i <= length(iter) || throw(BoundsError(iter, i))
19+
return Value(API.LLVMGetOperand(ref(iter.user), i-1))
20+
end
1921

2022
Base.setindex!(iter::UserOperandSet, val::Value, i) =
2123
API.LLVMSetOperand(ref(iter.user), i-1, ref(val))

test/core.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ Context() do ctx
6868
@test !isvararg(ft)
6969
@test return_type(ft) == x
7070
@test parameters(ft) == y
71+
@test_throws BoundsError parameters(ft)[3]
7172
end
7273

7374
# sequential
@@ -134,6 +135,7 @@ Context() do ctx
134135

135136
@test first(elem_it) == elem[1]
136137
@test last(elem_it) == elem[end]
138+
@test_throws BoundsError elem_it[3]
137139

138140
i = 1
139141
for el in elem_it
@@ -284,6 +286,7 @@ Context() do ctx
284286
@test length(ops) == 2
285287
@test ops[1] == first(parameters(fun))
286288
@test ops[2] == ConstantInt(LLVM.Int32Type(ctx), 1)
289+
@test_throws BoundsError ops[3]
287290
elseif i == 2
288291
@test length(ops) == 0
289292
@test collect(ops) == []
@@ -895,6 +898,7 @@ LLVM.Module("SomeModule", ctx) do mod
895898

896899
@test succ[1] == bb2
897900
@test succ[2] == bb3
901+
@test_throws BoundsError succ[3]
898902

899903
@test collect(succ) == [bb2, bb3]
900904
@test first(succ) == bb2

test/execution.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ function emit_phi(ctx::Context)
123123
append!(LLVM.incoming(phi), [(thencg, then), (elsecg, elsee)])
124124

125125
@test length(LLVM.incoming(phi)) == 2
126+
@test_throws BoundsError LLVM.incoming(phi)[3]
126127

127128
ret!(builder, phi)
128129
end
@@ -184,7 +185,7 @@ Context() do ctx
184185
end
185186
dispose.(args)
186187
end
187-
188+
188189
let mod1 = emit_sum(ctx), mod2 = emit_retint(ctx, 42)
189190
Interpreter(mod1) do engine
190191
@test_throws ErrorException collect(functions(engine))

0 commit comments

Comments
 (0)