@@ -2485,7 +2485,7 @@ function abstract_eval_setglobal!(interp::AbstractInterpreter, sv::AbsIntState,
24852485 (rt, exct) = global_assignment_rt_exct (interp, sv, saw_latestworld, gr, v)
24862486 return CallMeta (rt, exct, Effects (setglobal!_effects, nothrow= exct=== Bottom), GlobalAccessInfo (convert (Core. Binding, gr)))
24872487 end
2488- return CallMeta (Union{}, TypeError, EFFECTS_THROWS, NoCallInfo ())
2488+ return CallMeta (Union{}, Union{ TypeError, ErrorException} , EFFECTS_THROWS, NoCallInfo ())
24892489 end
24902490 ⊑ = partialorder (typeinf_lattice (interp))
24912491 if ! (hasintersect (widenconst (M), Module) && hasintersect (widenconst (s), Symbol))
@@ -3480,65 +3480,33 @@ function refine_partial_type(@nospecialize t)
34803480 return t
34813481end
34823482
3483- abstract_eval_nonlinearized_foreigncall_name (
3484- :: AbstractInterpreter , @nospecialize (e), :: StatementState , :: IRInterpretationState
3485- ) = nothing
3486-
3487- function abstract_eval_nonlinearized_foreigncall_name (
3488- interp:: AbstractInterpreter , @nospecialize (e), sstate:: StatementState , sv:: InferenceState
3489- )
3490- if isexpr (e, :call )
3491- n = length (e. args)
3492- argtypes = Vector {Any} (undef, n)
3493- callresult = Future {CallMeta} ()
3494- i:: Int = 1
3495- nextstate:: UInt8 = 0x0
3496- local ai, res
3497- function evalargs (interp, sv)
3498- if nextstate === 0x1
3499- @goto state1
3500- elseif nextstate === 0x2
3501- @goto state2
3502- end
3503- while i <= n
3504- ai = abstract_eval_nonlinearized_foreigncall_name (interp, e. args[i], sstate, sv)
3505- if ! isready (ai)
3506- nextstate = 0x1
3507- return false
3508- @label state1
3509- end
3510- argtypes[i] = ai[]. rt
3511- i += 1
3512- end
3513- res = abstract_call (interp, ArgInfo (e. args, argtypes), sstate, sv)
3514- if ! isready (res)
3515- nextstate = 0x2
3516- return false
3517- @label state2
3518- end
3519- callresult[] = res[]
3520- return true
3521- end
3522- evalargs (interp, sv) || push! (sv. tasks, evalargs)
3523- return callresult
3524- else
3525- return Future (abstract_eval_basic_statement (interp, e, sstate, sv))
3526- end
3527- end
3528-
35293483function abstract_eval_foreigncall (interp:: AbstractInterpreter , e:: Expr , sstate:: StatementState , sv:: AbsIntState )
35303484 callee = e. args[1 ]
3531- if isexpr (callee, :call ) && length (callee. args) > 1 && callee. args[1 ] == GlobalRef (Core, :tuple )
3532- # NOTE these expressions are not properly linearized
3533- abstract_eval_nonlinearized_foreigncall_name (interp, callee. args[2 ], sstate, sv)
3534- if length (callee. args) > 2
3535- abstract_eval_nonlinearized_foreigncall_name (interp, callee. args[3 ], sstate, sv)
3485+ if isexpr (callee, :tuple )
3486+ if length (callee. args) >= 1
3487+ # Evaluate the arguments to constrain the world, effects, and other info for codegen,
3488+ # but note there is an implied `if !=(C_NULL)` branch here that might read data
3489+ # in a different world (the exact cache behavior is unspecified), so we do not use
3490+ # these results to refine reachability of the subsequent foreigncall.
3491+ abstract_eval_value (interp, callee. args[1 ], sstate, sv)
3492+ if length (callee. args) >= 2
3493+ abstract_eval_value (interp, callee. args[2 ], sstate, sv)
3494+ # TODO : implement abstract_eval_nonlinearized_foreigncall_name correctly?
3495+ # lib_effects = abstract_call(interp, ArgInfo(e.args, Any[typeof(Libdl.dlopen), lib]), sstate, sv)::Future
3496+ end
35363497 end
35373498 else
35383499 abstract_eval_value (interp, callee, sstate, sv)
35393500 end
35403501 mi = frame_instance (sv)
35413502 t = sp_type_rewrap (e. args[2 ], mi, true )
3503+ let fptr = e. args[1 ]
3504+ if ! isexpr (fptr, :tuple )
3505+ if ! hasintersect (widenconst (abstract_eval_value (interp, fptr, sstate, sv)), Ptr)
3506+ return RTEffects (Bottom, Any, EFFECTS_THROWS)
3507+ end
3508+ end
3509+ end
35423510 for i = 3 : length (e. args)
35433511 if abstract_eval_value (interp, e. args[i], sstate, sv) === Bottom
35443512 return RTEffects (Bottom, Any, EFFECTS_THROWS)
@@ -3751,7 +3719,7 @@ end
37513719
37523720function global_assignment_rt_exct (interp:: AbstractInterpreter , sv:: AbsIntState , saw_latestworld:: Bool , g:: GlobalRef , @nospecialize (newty))
37533721 if saw_latestworld
3754- return Pair {Any,Any} (newty, ErrorException)
3722+ return Pair {Any,Any} (newty, Union{TypeError, ErrorException} )
37553723 end
37563724 newty′ = RefValue {Any} (newty)
37573725 (valid_worlds, ret) = scan_partitions (interp, g, sv. world) do interp:: AbstractInterpreter , :: Core.Binding , partition:: Core.BindingPartition
@@ -3766,15 +3734,16 @@ function global_assignment_binding_rt_exct(interp::AbstractInterpreter, partitio
37663734 if is_some_guard (kind)
37673735 return Pair {Any,Any} (newty, ErrorException)
37683736 elseif is_some_const_binding (kind) || is_some_imported (kind)
3769- return Pair {Any,Any} (Bottom, ErrorException)
3737+ # N.B.: Backdating should not improve inference in an earlier world
3738+ return Pair {Any,Any} (kind == PARTITION_KIND_BACKDATED_CONST ? newty : Bottom, ErrorException)
37703739 end
37713740 ty = kind == PARTITION_KIND_DECLARED ? Any : partition_restriction (partition)
37723741 wnewty = widenconst (newty)
37733742 if ! hasintersect (wnewty, ty)
3774- return Pair {Any,Any} (Bottom, ErrorException )
3743+ return Pair {Any,Any} (Bottom, TypeError )
37753744 elseif ! (wnewty <: ty )
37763745 retty = tmeet (typeinf_lattice (interp), newty, ty)
3777- return Pair {Any,Any} (retty, ErrorException )
3746+ return Pair {Any,Any} (retty, TypeError )
37783747 end
37793748 return Pair {Any,Any} (newty, Bottom)
37803749end
0 commit comments