@@ -2733,6 +2733,8 @@ function abstract_eval_isdefined(interp::AbstractInterpreter, e::Expr, vtypes::U
2733
2733
rt = Const (false ) # never assigned previously
2734
2734
elseif ! vtyp. undef
2735
2735
rt = Const (true ) # definitely assigned previously
2736
+ else # form `Conditional` to refine `vtyp.undef` in the then branch
2737
+ rt = Conditional (sym, vtyp. typ, vtyp. typ; isdefined= true )
2736
2738
end
2737
2739
elseif isa (sym, GlobalRef)
2738
2740
if InferenceParams (interp). assume_bindings_static
@@ -3205,7 +3207,7 @@ end
3205
3207
@inline function abstract_eval_basic_statement (interp:: AbstractInterpreter ,
3206
3208
@nospecialize (stmt), pc_vartable:: VarTable , frame:: InferenceState )
3207
3209
if isa (stmt, NewvarNode)
3208
- changes = StateUpdate (stmt. slot, VarState (Bottom, true ), false )
3210
+ changes = StateUpdate (stmt. slot, VarState (Bottom, true ))
3209
3211
return BasicStmtChange (changes, nothing , Union{})
3210
3212
elseif ! isa (stmt, Expr)
3211
3213
(; rt, exct) = abstract_eval_statement (interp, stmt, pc_vartable, frame)
@@ -3220,7 +3222,7 @@ end
3220
3222
end
3221
3223
lhs = stmt. args[1 ]
3222
3224
if isa (lhs, SlotNumber)
3223
- changes = StateUpdate (lhs, VarState (rt, false ), false )
3225
+ changes = StateUpdate (lhs, VarState (rt, false ))
3224
3226
elseif isa (lhs, GlobalRef)
3225
3227
handle_global_assignment! (interp, frame, lhs, rt)
3226
3228
elseif ! isa (lhs, SSAValue)
@@ -3230,7 +3232,7 @@ end
3230
3232
elseif hd === :method
3231
3233
fname = stmt. args[1 ]
3232
3234
if isa (fname, SlotNumber)
3233
- changes = StateUpdate (fname, VarState (Any, false ), false )
3235
+ changes = StateUpdate (fname, VarState (Any, false ))
3234
3236
end
3235
3237
return BasicStmtChange (changes, nothing , Union{})
3236
3238
elseif (hd === :code_coverage_effect || (
@@ -3576,7 +3578,7 @@ function apply_refinement!(𝕃ᵢ::AbstractLattice, slot::SlotNumber, @nospecia
3576
3578
oldtyp = vtype. typ
3577
3579
⊏ = strictpartialorder (𝕃ᵢ)
3578
3580
if newtyp ⊏ oldtyp
3579
- stmtupdate = StateUpdate (slot, VarState (newtyp, vtype. undef), false )
3581
+ stmtupdate = StateUpdate (slot, VarState (newtyp, vtype. undef))
3580
3582
stoverwrite1! (currstate, stmtupdate)
3581
3583
end
3582
3584
end
@@ -3600,7 +3602,9 @@ function conditional_change(𝕃ᵢ::AbstractLattice, currstate::VarTable, condt
3600
3602
# "causes" since we ignored those in the comparison
3601
3603
newtyp = tmerge (𝕃ᵢ, newtyp, LimitedAccuracy (Bottom, oldtyp. causes))
3602
3604
end
3603
- return StateUpdate (SlotNumber (condt. slot), VarState (newtyp, vtype. undef), true )
3605
+ # if this `Conditional` is from from `@isdefined condt.slot`, refine its `undef` information
3606
+ newundef = condt. isdefined ? ! then_or_else : vtype. undef
3607
+ return StateUpdate (SlotNumber (condt. slot), VarState (newtyp, newundef), #= conditional=# true )
3604
3608
end
3605
3609
3606
3610
function condition_object_change (currstate:: VarTable , condt:: Conditional ,
@@ -3609,7 +3613,7 @@ function condition_object_change(currstate::VarTable, condt::Conditional,
3609
3613
newcondt = Conditional (condt. slot,
3610
3614
then_or_else ? condt. thentype : Union{},
3611
3615
then_or_else ? Union{} : condt. elsetype)
3612
- return StateUpdate (condslot, VarState (newcondt, vtype. undef), false )
3616
+ return StateUpdate (condslot, VarState (newcondt, vtype. undef))
3613
3617
end
3614
3618
3615
3619
# make as much progress on `frame` as possible (by handling cycles)
0 commit comments