diff --git a/base/refvalue.jl b/base/refvalue.jl index 7cbb651d41aee..000088ff0ce76 100644 --- a/base/refvalue.jl +++ b/base/refvalue.jl @@ -45,7 +45,10 @@ function unsafe_convert(P::Union{Type{Ptr{T}},Type{Ptr{Cvoid}}}, b::RefValue{T}) # If it is actually an immutable, then we can't take it's pointer directly # Instead, explicitly load the pointer from the `RefValue`, # which also ensures this returns same pointer as the one rooted in the `RefValue` object. - p = pointerref(Ptr{Ptr{Cvoid}}(pointer_from_objref(b)), 1, Core.sizeof(Ptr{Cvoid})) + p = atomic_pointerref(Ptr{Ptr{Cvoid}}(pointer_from_objref(b)), :monotonic) + end + if p == C_NULL + throw(UndefRefError()) end return p end diff --git a/test/core.jl b/test/core.jl index a6926860ed8db..adf895ba471ea 100644 --- a/test/core.jl +++ b/test/core.jl @@ -7847,6 +7847,17 @@ import .Foo45350: x45350 f45350() = (global x45350 = 2) @test_throws ErrorException f45350() +@testset "Error behavior of unsafe_convert for RefValue" begin + b = Base.RefValue{Int}() + @test Base.unsafe_convert(Ptr{Int}, b) !== C_NULL + b = Base.RefValue{Base.RefValue{Int}}() + # throws because we hit `b.x` + @test_throws Core.UndefRefError Base.unsafe_convert(Ptr{Base.RefValue{Int}}, b) + # throws because we hit `b.x` + b = Base.RefValue{Integer}() + @test_throws Core.UndefRefError Base.unsafe_convert(Ptr{Integer}, b) +end + # #46503 - redefine `invoke`d methods foo46503(@nospecialize(a), b::Union{Vector{Any}, Float64, Nothing}) = rand() foo46503(a::Int, b::Nothing) = @invoke foo46503(a::Any, b)