Skip to content

Commit 63ecbcb

Browse files
committedOct 14, 2014
Merge pull request #8624 from JuliaLang/jcb/cfsimd
Reject `@simd` loops with break / continue / `@goto` in inner loop body
2 parents 821b6c5 + 797fd7b commit 63ecbcb

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed
 

‎NEWS.md

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ Library improvements
7474
* New `ordschur` and `ordschur!` functions for sorting a schur factorization by the eigenvalues.
7575

7676
* `deepcopy` recurses through immutable types and makes copies of their mutable fields ([#8560]).
77+
78+
* `@simd` now rejects invalid control flow (`@goto` / break / continue) in the inner loop body at compile time ([#8624]).
7779

7880
* Givens type doesn't have a size anymore and is no longer a subtype of AbstractMatrix ([#8660])
7981

‎base/simdloop.jl

+16
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,26 @@ function parse_iteration_space(x)
1919
x.args # symbol, range
2020
end
2121

22+
# reject invalid control flow statements in @simd loop body
23+
function check_body!(x::Expr)
24+
if x.head === :break || x.head == :continue
25+
throw(SimdError("$(x.head) is not allowed inside a @simd loop body"))
26+
elseif x.head === :macrocall && x.args[1] === symbol("@goto")
27+
throw(SimdError("$(x.args[1]) is not allowed inside a @simd loop body"))
28+
end
29+
for arg in x.args
30+
check_body!(arg)
31+
end
32+
return true
33+
end
34+
check_body!(x::QuoteNode) = check_body!(x.value)
35+
check_body!(x) = true
36+
2237
# Compile Expr x in context of @simd.
2338
function compile(x)
2439
(isa(x, Expr) && x.head == :for) || throw(SimdError("for loop expected"))
2540
length(x.args) == 2 || throw(SimdError("1D for loop expected"))
41+
check_body!(x)
2642

2743
var,range = parse_iteration_space(x.args[1])
2844
r = gensym("r") # Range value

‎test/simdloop.jl

+23
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,26 @@ let j=4
6767
end
6868
@test !simd_loop_local_present
6969
end
70+
71+
import Base.SimdLoop.SimdError
72+
73+
# Test that @simd rejects inner loop body with invalid control flow statements
74+
# issue #8613
75+
@test_throws SimdError eval(:(begin
76+
@simd for x = 1:10
77+
x == 1 && break
78+
end
79+
end))
80+
81+
@test_throws SimdError eval(:(begin
82+
@simd for x = 1:10
83+
x < 5 && continue
84+
end
85+
end))
86+
87+
@test_throws SimdError eval(:(begin
88+
@simd for x = 1:10
89+
x == 1 || @goto exit_loop
90+
end
91+
@label exit_loop
92+
end))

0 commit comments

Comments
 (0)
Please sign in to comment.