Skip to content

Commit

Permalink
inference: fix [modifyfield!|replacefield!]_tfuncs (#56310)
Browse files Browse the repository at this point in the history
Currently the following code snippet results in an internal error:
```julia
julia> func(x) = @atomic :monotonic x[].count += 1;

julia> let;Base.Experimental.@force_compile
           x = Ref(nothing)
           func(x)
       end
Internal error: during type inference of
...
```

This issue is caused by the incorrect use of `_fieldtype_tfunc(𝕃, o, f)`
within `modifyfield!_tfunc`, specifically because `o` should be
`widenconst`ed, but it isn’t. By using `_fieldtype_tfunc` correctly, we
can avoid the error through error-catching in `abstract_modifyop!`. This
commit also includes a similar fix for `replacefield!_tfunc` as well.
  • Loading branch information
aviatesk authored Oct 25, 2024
1 parent ac5bb66 commit 29b509d
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
6 changes: 4 additions & 2 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1347,13 +1347,15 @@ end
return getfield_tfunc(𝕃, o, f)
end
@nospecs function modifyfield!_tfunc(𝕃::AbstractLattice, o, f, op, v, order=Symbol)
T = _fieldtype_tfunc(𝕃, o, f, isconcretetype(o))
oβ€² = widenconst(o)
T = _fieldtype_tfunc(𝕃, oβ€², f, isconcretetype(oβ€²))
T === Bottom && return Bottom
PT = Const(Pair)
return instanceof_tfunc(apply_type_tfunc(𝕃, PT, T, T), true)[1]
end
@nospecs function replacefield!_tfunc(𝕃::AbstractLattice, o, f, x, v, success_order=Symbol, failure_order=Symbol)
T = _fieldtype_tfunc(𝕃, o, f, isconcretetype(o))
oβ€² = widenconst(o)
T = _fieldtype_tfunc(𝕃, oβ€², f, isconcretetype(oβ€²))
T === Bottom && return Bottom
PT = Const(ccall(:jl_apply_cmpswap_type, Any, (Any,), T) where T)
return instanceof_tfunc(apply_type_tfunc(𝕃, PT, T), true)[1]
Expand Down
15 changes: 15 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6063,3 +6063,18 @@ end === Union{}
@test Base.infer_return_type() do
TypeVar(:Issue56248, Any, 1)
end === Union{}

@test Base.infer_return_type((Nothing,)) do x
@atomic x.count += 1
end == Union{}
@test Base.infer_return_type((Nothing,)) do x
@atomicreplace x.count 0 => 1
end == Union{}
mutable struct AtomicModifySafety
@atomic count::Int
end
let src = code_typed((Union{Nothing,AtomicModifySafety},)) do x
@atomic x.count += 1
end |> only |> first
@test any(@nospecialize(x)->Meta.isexpr(x, :invoke_modify), src.code)
end

0 comments on commit 29b509d

Please sign in to comment.