Skip to content

Commit

Permalink
Throw an error if trying to access unassigned data in Base.RefValue (#…
Browse files Browse the repository at this point in the history
…45829)

Co-authored-by: Kristoffer Carlsson <kcarlsson89@gmail.com>
  • Loading branch information
vchuravy and KristofferC authored Feb 13, 2023
1 parent 3e37734 commit cc1c6a6
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
5 changes: 4 additions & 1 deletion base/refvalue.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit cc1c6a6

Please sign in to comment.