Skip to content

Commit

Permalink
Reject @simd loops with break / continue / @goto in inner loop body
Browse files Browse the repository at this point in the history
See #8613
  • Loading branch information
jakebolewski committed Oct 8, 2014
1 parent 9f238c5 commit 69d7058
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
16 changes: 16 additions & 0 deletions base/simdloop.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,26 @@ function parse_iteration_space(x)
x.args # symbol, range
end

# reject invalid control flow statements in @simd loop body
function check_body!(x::Expr)
if x.head === :break || x.head == :continue
throw(SimdError("$(x.head) is not allowed inside a @simd loop body"))
elseif x.head === :macrocall && x.args[1] === symbol("@goto")
throw(SimdError("$(x.args[1]) is not allowed inside a @simd loop body"))
end
for arg in x.args
check_body!(arg)
end
return true
end
check_body!(x::QuoteNode) = check_body!(x.value)
check_body!(x) = true

# Compile Expr x in context of @simd.
function compile(x)
(isa(x, Expr) && x.head == :for) || throw(SimdError("for loop expected"))
length(x.args) == 2 || throw(SimdError("1D for loop expected"))
check_body!(x)

var,range = parse_iteration_space(x.args[1])
r = gensym("r") # Range value
Expand Down
23 changes: 23 additions & 0 deletions test/simdloop.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,26 @@ let j=4
end
@test !simd_loop_local_present
end

import Base.SimdLoop.SimdError

# Test that @simd rejects inner loop body with invalid control flow statements
# issue #8613
@test_throws SimdError eval(:(begin
@simd for x = 1:10
x == 1 && break
end
end))

@test_throws SimdError eval(:(begin
@simd for x = 1:10
x < 5 && continue
end
end))

@test_throws SimdError eval(:(begin
@simd for x = 1:10
x == 1 || @goto exit_loop
end
@label exit_loop
end))

0 comments on commit 69d7058

Please sign in to comment.