From 0b48b91c9881823d860eaf0a605072b7f20a4cbb Mon Sep 17 00:00:00 2001 From: Aditya Puranik <7466364+Ellipse0934@users.noreply.github.com> Date: Mon, 21 Feb 2022 15:17:52 +0530 Subject: [PATCH] Fix aliasing bug in copy!(x, x) for x::AbstractSet and x::AbstractDict, fixes #41268 (#44265) --- base/abstractdict.jl | 5 ++++- base/abstractset.jl | 5 ++++- test/dict.jl | 2 ++ test/sets.jl | 3 +++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/base/abstractdict.jl b/base/abstractdict.jl index a9c04dac22b7b..daab71c3cc671 100644 --- a/base/abstractdict.jl +++ b/base/abstractdict.jl @@ -189,7 +189,10 @@ empty(a::AbstractDict) = empty(a, keytype(a), valtype(a)) empty(a::AbstractDict, ::Type{V}) where {V} = empty(a, keytype(a), V) # Note: this is the form which makes sense for `Vector`. copy(a::AbstractDict) = merge!(empty(a), a) -copy!(dst::AbstractDict, src::AbstractDict) = merge!(empty!(dst), src) +function copy!(dst::AbstractDict, src::AbstractDict) + dst === src && return dst + merge!(empty!(dst), src) +end """ merge!(d::AbstractDict, others::AbstractDict...) diff --git a/base/abstractset.jl b/base/abstractset.jl index bec4a84b19d15..561e18c15697c 100644 --- a/base/abstractset.jl +++ b/base/abstractset.jl @@ -3,7 +3,10 @@ eltype(::Type{<:AbstractSet{T}}) where {T} = @isdefined(T) ? T : Any sizehint!(s::AbstractSet, n) = nothing -copy!(dst::AbstractSet, src::AbstractSet) = union!(empty!(dst), src) +function copy!(dst::AbstractSet, src::AbstractSet) + dst === src && return dst + union!(empty!(dst), src) +end ## set operations (union, intersection, symmetric difference) diff --git a/test/dict.jl b/test/dict.jl index cbbb475c993fd..ad15764a09d16 100644 --- a/test/dict.jl +++ b/test/dict.jl @@ -1179,6 +1179,8 @@ end @test s === copy!(s, Base.ImmutableDict(a[])) == Dict(a[]) end end + s2 = copy(s) + @test copy!(s, s) == s2 end @testset "map!(f, values(dict))" begin diff --git a/test/sets.jl b/test/sets.jl index 43ba433e780d7..1999dbf3d020f 100644 --- a/test/sets.jl +++ b/test/sets.jl @@ -151,6 +151,9 @@ end @test s === copy!(s, BitSet(a)) == S(a) end end + s = Set([1, 2]) + s2 = copy(s) + @test copy!(s, s) == s2 end @testset "sizehint, empty" begin