Skip to content

Commit

Permalink
inference: guard fieldtype calls more also against invalid types
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Sep 26, 2023
1 parent 33f391c commit 3413ed7
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 23 deletions.
49 changes: 27 additions & 22 deletions base/compiler/tfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1223,31 +1223,36 @@ end
return Bottom
end
if nf == 1
return rewrap_unionall(unwrapva(ftypes[1]), s00)
end
# union together types of all fields
t = Bottom
for i in 1:nf
_ft = ftypes[i]
setfield && isconst(s, i) && continue
t = tmerge(t, rewrap_unionall(unwrapva(_ft), s00))
t === Any && break
fld = 1
else
# union together types of all fields
t = Bottom
for i in 1:nf
_ft = unwrapva(ftypes[i])
valid_as_lattice(_ft, true) || continue
setfield && isconst(s, i) && continue
t = tmerge(t, rewrap_unionall(_ft, s00))
t === Any && break
end
return t
end
return t
else
fld = _getfield_fieldindex(s, name)
fld === nothing && return Bottom
end
fld = _getfield_fieldindex(s, name)
fld === nothing && return Bottom
if s <: Tuple && fld >= nf && isvarargtype(ftypes[nf])
return rewrap_unionall(unwrapva(ftypes[nf]), s00)
end
if fld < 1 || fld > nf
return Bottom
elseif setfield && isconst(s, fld)
return Bottom
end
R = ftypes[fld]
if isempty(s.parameters)
return R
R = unwrapva(ftypes[nf])
else
if fld < 1 || fld > nf
return Bottom
elseif setfield && isconst(s, fld)
return Bottom
end
R = ftypes[fld]
valid_as_lattice(R, true) || return Bottom
if isempty(s.parameters)
return R
end
end
return rewrap_unionall(R, s00)
end
Expand Down
2 changes: 1 addition & 1 deletion base/compiler/typeutils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ has_concrete_subtype(d::DataType) = d.flags & 0x0020 == 0x0020 # n.b. often comp

# determine whether x is a valid lattice element
# For example, Type{v} is not valid if v is a value
# Accepts TypeVars also, since it assumes the user will rewrap it correctly
# Accepts TypeVars and has_free_typevar also, since it assumes the user will rewrap it correctly
# If astag is true, then also requires that it be a possible type tag for a valid object
function valid_as_lattice(@nospecialize(x), astag::Bool=false)
x === Bottom && false
Expand Down
14 changes: 14 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5263,3 +5263,17 @@ f51228() = f51228(whatever_unknown_value51228)
f51228(x) = 1
f51228(::Vararg{T,T}) where {T} = "2"
@test only(Base.return_types(f51228, ())) == Int

struct A51317
b::Tuple{1}
A1() = new()
end
struct An51317
a::Int
b::Tuple{1}
An51317() = new()
end
@test only(Base.return_types((x,f) -> getfield(x, f), (A51317, Symbol))) === Union{}
@test only(Base.return_types((x,f) -> getfield(x, f), (An51317, Symbol))) === Int
@test only(Base.return_types(x -> getfield(x, :b), (A51317,))) === Union{}
@test only(Base.return_types(x -> getfield(x, :b), (An51317,))) === Union{}

0 comments on commit 3413ed7

Please sign in to comment.