Skip to content

Commit

Permalink
inference: refine setglobal! rt for invalid assignments
Browse files Browse the repository at this point in the history
  • Loading branch information
aviatesk committed Nov 20, 2024
1 parent bdd4e05 commit df74a79
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 14 deletions.
31 changes: 17 additions & 14 deletions Compiler/src/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2415,8 +2415,8 @@ function abstract_eval_setglobal!(interp::AbstractInterpreter, sv::AbsIntState,
if isa(M, Const) && isa(s, Const)
M, s = M.val, s.val
if M isa Module && s isa Symbol
exct = global_assignment_exct(interp, sv, GlobalRef(M, s), v)
return CallMeta(v, exct, Effects(setglobal!_effects, nothrow=exct===Bottom), NoCallInfo())
rt, exct = global_assignment_rt_exct(interp, sv, GlobalRef(M, s), v)
return CallMeta(rt, exct, Effects(setglobal!_effects, nothrow=exct===Bottom), NoCallInfo())
end
return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo())
end
Expand Down Expand Up @@ -2481,7 +2481,7 @@ function abstract_eval_replaceglobal!(interp::AbstractInterpreter, sv::AbsIntSta
if binding_kind(partition) == BINDING_KIND_GLOBAL
T = partition_restriction(partition)
end
exct = Union{rte.exct, global_assignment_binding_exct(partition, v)}
exct = Union{rte.exct, global_assignment_binding_rt_exct(partition, v)[2]}
effects = merge_effects(rte.effects, Effects(setglobal!_effects, nothrow=exct===Bottom))
sg = CallMeta(Any, exct, effects, NoCallInfo())
else
Expand Down Expand Up @@ -3396,28 +3396,31 @@ function abstract_eval_globalref(interp::AbstractInterpreter, g::GlobalRef, sv::
return ret
end

function global_assignment_exct(interp::AbstractInterpreter, sv::AbsIntState, g::GlobalRef, @nospecialize(newty))
function global_assignment_rt_exct(interp::AbstractInterpreter, sv::AbsIntState, g::GlobalRef, @nospecialize(newty))
partition = abstract_eval_binding_partition!(interp, g, sv)
return global_assignment_binding_exct(partition, newty)
return global_assignment_binding_rt_exct(partition, newty)
end

function global_assignment_binding_exct(partition::Core.BindingPartition, @nospecialize(newty))
function global_assignment_binding_rt_exct(partition::Core.BindingPartition, @nospecialize(newty))
kind = binding_kind(partition)
if is_some_guard(kind) || is_some_const_binding(kind)
return ErrorException
if is_some_guard(kind)
return Pair{Any,Any}(newty, ErrorException)
elseif is_some_const_binding(kind)
return Pair{Any,Any}(Union{}, ErrorException)
end

ty = partition_restriction(partition)
if !(widenconst(newty) <: ty)
return TypeError
wnewty = widenconst(newty)
if !hasintersect(wnewty, ty)
return Pair{Any,Any}(Bottom, TypeError)
elseif !(wnewty <: ty)
return Pair{Any,Any}(newty, TypeError)
end

return Union{}
return Pair{Any,Any}(newty, Union{})
end

function handle_global_assignment!(interp::AbstractInterpreter, frame::InferenceState, lhs::GlobalRef, @nospecialize(newty))
effect_free = ALWAYS_FALSE
nothrow = global_assignment_exct(interp, frame, lhs, ignorelimited(newty)) === Union{}
nothrow = global_assignment_rt_exct(interp, frame, lhs, ignorelimited(newty))[2] === Union{}
inaccessiblememonly = ALWAYS_FALSE
if !nothrow
sub_curr_ssaflag!(frame, IR_FLAG_NOTHROW)
Expand Down
5 changes: 5 additions & 0 deletions Compiler/test/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6088,3 +6088,8 @@ function issue56387(nt::NamedTuple, field::Symbol=:a)
types[index]
end
@test Base.infer_return_type(issue56387, (typeof((;a=1)),)) == Type{Int}

global setglobal!_must_throw::Int = 42
@test Base.infer_return_type((String,)) do x
setglobal!(@__MODULE__, :setglobal!_must_throw, x)
end === Union{}

0 comments on commit df74a79

Please sign in to comment.