Skip to content

Commit 45d3238

Browse files
topolarityKristofferC
authored and
KristofferC
committed
lowering: don't reverse handler order in (pop-handler-list ...) (#55871)
We were accidentally emitting a different pop order for `Expr(:leave, ...)` if you uncomment the `nothing` below: ```julia let src = Meta.@lower let try try return 1 catch end finally # nothing # <- uncomment me end end println.(filter(stmt->Base.isexpr(stmt, :leave), src.args[1].code)) nothing end ``` (cherry picked from commit deac82a)
1 parent 0ff8f82 commit 45d3238

File tree

2 files changed

+46
-9
lines changed

2 files changed

+46
-9
lines changed

src/julia-syntax.scm

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4363,15 +4363,16 @@ f(x) = yt(x)
43634363
(define (pop-handler-list src-tokens dest-tokens lab)
43644364
(if (eq? src-tokens dest-tokens)
43654365
#f
4366-
(let loop ((s src-tokens)
4367-
(l '()))
4368-
(if (not (pair? s))
4369-
(if (null? lab)
4370-
(error "Attempt to jump into catch block")
4371-
(error (string "cannot goto label \"" lab "\" inside try/catch block"))))
4372-
(if (eq? (cdr s) dest-tokens)
4373-
(cons (car s) l)
4374-
(loop (cdr s) (cons (car s) l))))))
4366+
(reverse
4367+
(let loop ((s src-tokens)
4368+
(l '()))
4369+
(if (not (pair? s))
4370+
(if (null? lab)
4371+
(error "Attempt to jump into catch block")
4372+
(error (string "cannot goto label \"" lab "\" inside try/catch block"))))
4373+
(if (eq? (cdr s) dest-tokens)
4374+
(cons (car s) l)
4375+
(loop (cdr s) (cons (car s) l)))))))
43754376
(define (emit-return tail x)
43764377
(define (emit- x)
43774378
(let* ((tmp (if ((if (null? catch-token-stack) valid-ir-return? simple-atom?) x)

test/syntax.jl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3691,6 +3691,42 @@ begin
36913691
end
36923692
@test Foreign54607.bar == 9
36933693

3694+
# Test that lowering doesn't accidentally put a `Module` in the Method name slot
3695+
let src = @Meta.lower let capture=1
3696+
global foo_lower_block
3697+
foo_lower_block() = capture
3698+
end
3699+
code = src.args[1].code
3700+
for i = length(code):-1:1
3701+
expr = code[i]
3702+
Meta.isexpr(expr, :method) || continue
3703+
@test isa(expr.args[1], Union{GlobalRef, Symbol})
3704+
end
3705+
end
3706+
3707+
let src = Meta.@lower let
3708+
try
3709+
try
3710+
return 1
3711+
catch
3712+
end
3713+
finally
3714+
nothing
3715+
end
3716+
end
3717+
code = src.args[1].code
3718+
for stmt in code
3719+
if Meta.isexpr(stmt, :leave) && length(stmt.args) > 1
3720+
# Expr(:leave, ...) should list the arguments to pop from
3721+
# inner-most scope to outer-most
3722+
@test issorted(Int[
3723+
(arg::Core.SSAValue).id
3724+
for arg in stmt.args
3725+
]; rev=true)
3726+
end
3727+
end
3728+
end
3729+
36943730
# Test that globals can be `using`'d even if they are not yet defined
36953731
module UndefGlobal54954
36963732
global theglobal54954::Int

0 commit comments

Comments
 (0)