From deac82ad915db6c1fd6e9246fd4bb3310b7cd71f Mon Sep 17 00:00:00 2001 From: Cody Tapscott <84105208+topolarity@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:40:02 -0500 Subject: [PATCH] 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 ``` --- src/julia-syntax.scm | 19 ++++++++++--------- test/syntax.jl | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index e82c436e5a730..6a9558bb06ba5 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -4447,15 +4447,16 @@ f(x) = yt(x) (define (pop-handler-list src-tokens dest-tokens lab) (if (eq? src-tokens dest-tokens) #f - (let loop ((s src-tokens) - (l '())) - (if (not (pair? s)) - (if (null? lab) - (error "Attempt to jump into catch block") - (error (string "cannot goto label \"" lab "\" inside try/catch block")))) - (if (eq? (cdr s) dest-tokens) - (cons (car s) l) - (loop (cdr s) (cons (car s) l)))))) + (reverse + (let loop ((s src-tokens) + (l '())) + (if (not (pair? s)) + (if (null? lab) + (error "Attempt to jump into catch block") + (error (string "cannot goto label \"" lab "\" inside try/catch block")))) + (if (eq? (cdr s) dest-tokens) + (cons (car s) l) + (loop (cdr s) (cons (car s) l))))))) (define (emit-return tail x) (define (emit- x) (let* ((tmp (if ((if (null? catch-token-stack) valid-ir-return? simple-atom?) x) diff --git a/test/syntax.jl b/test/syntax.jl index c19721b5c54b3..1f9d1d592931b 100644 --- a/test/syntax.jl +++ b/test/syntax.jl @@ -3865,6 +3865,29 @@ end end end +let src = Meta.@lower let + try + try + return 1 + catch + end + finally + nothing + end +end + code = src.args[1].code + for stmt in code + if Meta.isexpr(stmt, :leave) && length(stmt.args) > 1 + # Expr(:leave, ...) should list the arguments to pop from + # inner-most scope to outer-most + @test issorted(Int[ + (arg::Core.SSAValue).id + for arg in stmt.args + ]; rev=true) + end + end +end + # Test that globals can be `using`'d even if they are not yet defined module UndefGlobal54954 global theglobal54954::Int