Skip to content

Commit 6ec2b1f

Browse files
authored
Handle no-postdominator case in finalizer pass (#54765)
This pass was assuming that the post-dominator of all finalizer uses exists as a real BB in the CFG. Resolves #54596
1 parent f1c601d commit 6ec2b1f

File tree

3 files changed

+24
-0
lines changed

3 files changed

+24
-0
lines changed

base/compiler/ssair/domtree.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,8 @@ end
657657
Compute the nearest common (post-)dominator of `a` and `b`.
658658
"""
659659
function nearest_common_dominator(domtree::GenericDomTree, a::BBNumber, b::BBNumber)
660+
a == 0 && return a
661+
b == 0 && return b
660662
alevel = domtree.nodes[a].level
661663
blevel = domtree.nodes[b].level
662664
# W.l.g. assume blevel <= alevel

base/compiler/ssair/passes.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,6 +1614,7 @@ function try_resolve_finalizer!(ir::IRCode, idx::Int, finalizer_idx::Int, defuse
16141614
end
16151615
all(check_defuse, defuse.uses) || return nothing
16161616
all(check_defuse, defuse.defs) || return nothing
1617+
bb_insert_block != 0 || return nothing # verify post-dominator of all uses exists
16171618

16181619
# Check #3
16191620
dominates(domtree, finalizer_bb, bb_insert_block) || return nothing

test/compiler/irpasses.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,3 +1949,24 @@ let code = Any[
19491949
# fallthrough
19501950
@test isdefined(ir[SSAValue(gotoifnot+1)][:inst]::ReturnNode, :val)
19511951
end
1952+
1953+
# https://github.com/JuliaLang/julia/issues/54596
1954+
# finalized object's uses have no postdominator
1955+
let f = (x)->nothing, mi = Base.method_instance(f, (Base.RefValue{Nothing},)), code = Any[
1956+
# Basic Block 1
1957+
Expr(:new, Base.RefValue{Nothing}, nothing)
1958+
Expr(:call, Core.finalizer, f, SSAValue(1), true, mi)
1959+
GotoIfNot(false, 6)
1960+
# Basic Block 2
1961+
Expr(:call, Base.getfield, SSAValue(1), :x)
1962+
ReturnNode(SSAValue(4))
1963+
# Basic Block 3
1964+
Expr(:call, Base.getfield, SSAValue(1), :x)
1965+
ReturnNode(SSAValue(6))
1966+
]
1967+
ir = make_ircode(code; ssavaluetypes=Any[Base.RefValue{Nothing}, Nothing, Any, Nothing, Any, Nothing, Any])
1968+
inlining = Core.Compiler.InliningState(Core.Compiler.NativeInterpreter())
1969+
Core.Compiler.verify_ir(ir)
1970+
ir = Core.Compiler.sroa_pass!(ir, inlining)
1971+
Core.Compiler.verify_ir(ir)
1972+
end

0 commit comments

Comments
 (0)