Skip to content

Commit

Permalink
Add test for WeakKeyDict soundness
Browse files Browse the repository at this point in the history
The underlying issues was addressed with the change in WeakRef
semantics in #38180. However, we still want the test.
Closes #38727
  • Loading branch information
Keno committed Dec 9, 2020
1 parent 811e2c0 commit 0ba3287
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions test/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1162,3 +1162,42 @@ end
@test testdict[:b] == 1
end
end

# WeakKeyDict soundness (#38727)
mutable struct ComparesWithGC38727
i::Int
end
const armed = Ref{Bool}(true)
@noinline fwdab38727(a, b) = invoke(Base.isequal, Tuple{Any, WeakRef}, a, b)
function Base.isequal(a::ComparesWithGC38727, b::WeakRef)
# This GC.gc() here simulates a GC during compilation in the original issue
armed[] && GC.gc()
armed[] = false
fwdab38727(a, b)
end
Base.isequal(a::WeakRef, b::ComparesWithGC38727) = isequal(b, a)
Base.:(==)(a::ComparesWithGC38727, b::ComparesWithGC38727) = a.i == b.i
Base.hash(a::ComparesWithGC38727, u::UInt) = Base.hash(a.i, u)
function make_cwgc38727(wkd, i)
f = ComparesWithGC38727(i)
function fin(f)
f.i = -1
end
finalizer(fin, f)
f
end
@noinline mk38727(wkd) = wkd[make_cwgc38727(wkd, 1)] = nothing
function bar()
wkd = WeakKeyDict{Any, Nothing}()
mk38727(wkd)
armed[] = true
z = getkey(wkd, ComparesWithGC38727(1), missing)
end
# Run this twice, in case compilation the first time around
# masks something.
let c = bar()
@test c === missing || c == ComparesWithGC38727(1)
end
let c = bar()
@test c === missing || c == ComparesWithGC38727(1)
end

0 comments on commit 0ba3287

Please sign in to comment.