Skip to content

Commit 3413ed7

Browse files
committed
inference: guard fieldtype calls more also against invalid types
1 parent 33f391c commit 3413ed7

File tree

3 files changed

+42
-23
lines changed

3 files changed

+42
-23
lines changed

base/compiler/tfuncs.jl

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,31 +1223,36 @@ end
12231223
return Bottom
12241224
end
12251225
if nf == 1
1226-
return rewrap_unionall(unwrapva(ftypes[1]), s00)
1227-
end
1228-
# union together types of all fields
1229-
t = Bottom
1230-
for i in 1:nf
1231-
_ft = ftypes[i]
1232-
setfield && isconst(s, i) && continue
1233-
t = tmerge(t, rewrap_unionall(unwrapva(_ft), s00))
1234-
t === Any && break
1226+
fld = 1
1227+
else
1228+
# union together types of all fields
1229+
t = Bottom
1230+
for i in 1:nf
1231+
_ft = unwrapva(ftypes[i])
1232+
valid_as_lattice(_ft, true) || continue
1233+
setfield && isconst(s, i) && continue
1234+
t = tmerge(t, rewrap_unionall(_ft, s00))
1235+
t === Any && break
1236+
end
1237+
return t
12351238
end
1236-
return t
1239+
else
1240+
fld = _getfield_fieldindex(s, name)
1241+
fld === nothing && return Bottom
12371242
end
1238-
fld = _getfield_fieldindex(s, name)
1239-
fld === nothing && return Bottom
12401243
if s <: Tuple && fld >= nf && isvarargtype(ftypes[nf])
1241-
return rewrap_unionall(unwrapva(ftypes[nf]), s00)
1242-
end
1243-
if fld < 1 || fld > nf
1244-
return Bottom
1245-
elseif setfield && isconst(s, fld)
1246-
return Bottom
1247-
end
1248-
R = ftypes[fld]
1249-
if isempty(s.parameters)
1250-
return R
1244+
R = unwrapva(ftypes[nf])
1245+
else
1246+
if fld < 1 || fld > nf
1247+
return Bottom
1248+
elseif setfield && isconst(s, fld)
1249+
return Bottom
1250+
end
1251+
R = ftypes[fld]
1252+
valid_as_lattice(R, true) || return Bottom
1253+
if isempty(s.parameters)
1254+
return R
1255+
end
12511256
end
12521257
return rewrap_unionall(R, s00)
12531258
end

base/compiler/typeutils.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ has_concrete_subtype(d::DataType) = d.flags & 0x0020 == 0x0020 # n.b. often comp
9797

9898
# determine whether x is a valid lattice element
9999
# For example, Type{v} is not valid if v is a value
100-
# Accepts TypeVars also, since it assumes the user will rewrap it correctly
100+
# Accepts TypeVars and has_free_typevar also, since it assumes the user will rewrap it correctly
101101
# If astag is true, then also requires that it be a possible type tag for a valid object
102102
function valid_as_lattice(@nospecialize(x), astag::Bool=false)
103103
x === Bottom && false

test/compiler/inference.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5263,3 +5263,17 @@ f51228() = f51228(whatever_unknown_value51228)
52635263
f51228(x) = 1
52645264
f51228(::Vararg{T,T}) where {T} = "2"
52655265
@test only(Base.return_types(f51228, ())) == Int
5266+
5267+
struct A51317
5268+
b::Tuple{1}
5269+
A1() = new()
5270+
end
5271+
struct An51317
5272+
a::Int
5273+
b::Tuple{1}
5274+
An51317() = new()
5275+
end
5276+
@test only(Base.return_types((x,f) -> getfield(x, f), (A51317, Symbol))) === Union{}
5277+
@test only(Base.return_types((x,f) -> getfield(x, f), (An51317, Symbol))) === Int
5278+
@test only(Base.return_types(x -> getfield(x, :b), (A51317,))) === Union{}
5279+
@test only(Base.return_types(x -> getfield(x, :b), (An51317,))) === Union{}

0 commit comments

Comments
 (0)