Skip to content

Commit 7e5f691

Browse files
authored
inference: add some error checks for atomic getfield with boundscheck (#43651)
1 parent dab212e commit 7e5f691

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

base/compiler/tfuncs.jl

+22-5
Original file line numberDiff line numberDiff line change
@@ -713,11 +713,12 @@ function getfield_nothrow(@nospecialize(s00), @nospecialize(name), boundscheck::
713713
sv = s00.val
714714
end
715715
if isa(name, Const)
716-
if !isa(name.val, Symbol)
716+
nval = name.val
717+
if !isa(nval, Symbol)
717718
isa(sv, Module) && return false
718-
isa(name.val, Int) || return false
719+
isa(nval, Int) || return false
719720
end
720-
return isdefined(sv, name.val)
721+
return isdefined(sv, nval)
721722
end
722723
if !boundscheck && !isa(sv, Module)
723724
# If bounds checking is disabled and all fields are assigned,
@@ -756,8 +757,24 @@ function getfield_nothrow(@nospecialize(s00), @nospecialize(name), boundscheck::
756757
return false
757758
end
758759

759-
getfield_tfunc(s00, name, boundscheck_or_order) = (@nospecialize; getfield_tfunc(s00, name))
760-
getfield_tfunc(s00, name, order, boundscheck) = (@nospecialize; getfield_tfunc(s00, name))
760+
function getfield_tfunc(s00, name, boundscheck_or_order)
761+
@nospecialize
762+
t = isvarargtype(boundscheck_or_order) ? unwrapva(boundscheck_or_order) :
763+
widenconst(boundscheck_or_order)
764+
hasintersect(t, Symbol) || hasintersect(t, Bool) || return Bottom
765+
return getfield_tfunc(s00, name)
766+
end
767+
function getfield_tfunc(s00, name, order, boundscheck)
768+
@nospecialize
769+
hasintersect(widenconst(order), Symbol) || return Bottom
770+
if isvarargtype(boundscheck)
771+
t = unwrapva(boundscheck)
772+
hasintersect(t, Symbol) || hasintersect(t, Bool) || return Bottom
773+
else
774+
hasintersect(widenconst(boundscheck), Bool) || return Bottom
775+
end
776+
return getfield_tfunc(s00, name)
777+
end
761778
function getfield_tfunc(@nospecialize(s00), @nospecialize(name))
762779
s = unwrap_unionall(s00)
763780
if isa(s, Union)

test/compiler/inference.jl

+18-1
Original file line numberDiff line numberDiff line change
@@ -1608,7 +1608,7 @@ f_pure_add() = (1 + 1 == 2) ? true : "FAIL"
16081608
@test Core.Compiler.getfield_tfunc(Core.TypeName, Const(:flags)) == UInt8
16091609

16101610
# getfield on abstract named tuples. issue #32698
1611-
import Core.Compiler.getfield_tfunc
1611+
import Core.Compiler: getfield_tfunc, Const
16121612
@test getfield_tfunc(NamedTuple{(:id, :y), T} where {T <: Tuple{Int, Union{Float64, Missing}}},
16131613
Const(:y)) == Union{Missing, Float64}
16141614
@test getfield_tfunc(NamedTuple{(:id, :y), T} where {T <: Tuple{Int, Union{Float64, Missing}}},
@@ -1622,6 +1622,23 @@ import Core.Compiler.getfield_tfunc
16221622
@test getfield_tfunc(NamedTuple{<:Any, T} where {T <: Tuple{Int, Union{Float64, Missing}}},
16231623
Const(:x)) == Union{Missing, Float64, Int}
16241624

1625+
mutable struct ARef{T}
1626+
@atomic x::T
1627+
end
1628+
@test getfield_tfunc(ARef{Int},Const(:x),Symbol) === Int
1629+
@test getfield_tfunc(ARef{Int},Const(:x),Bool) === Int
1630+
@test getfield_tfunc(ARef{Int},Const(:x),Symbol,Bool) === Int
1631+
@test getfield_tfunc(ARef{Int},Const(:x),Symbol,Vararg{Symbol}) === Int # `Vararg{Symbol}` might be empty
1632+
@test getfield_tfunc(ARef{Int},Const(:x),Vararg{Symbol}) === Int
1633+
@test getfield_tfunc(ARef{Int},Const(:x),Any,) === Int
1634+
@test getfield_tfunc(ARef{Int},Const(:x),Any,Any) === Int
1635+
@test getfield_tfunc(ARef{Int},Const(:x),Any,Vararg{Any}) === Int
1636+
@test getfield_tfunc(ARef{Int},Const(:x),Vararg{Any}) === Int
1637+
@test getfield_tfunc(ARef{Int},Const(:x),Int) === Union{}
1638+
@test getfield_tfunc(ARef{Int},Const(:x),Bool,Symbol) === Union{}
1639+
@test getfield_tfunc(ARef{Int},Const(:x),Symbol,Symbol) === Union{}
1640+
@test getfield_tfunc(ARef{Int},Const(:x),Bool,Bool) === Union{}
1641+
16251642
struct Foo_22708
16261643
x::Ptr{Foo_22708}
16271644
end

0 commit comments

Comments
 (0)