Skip to content

Commit 4efebe7

Browse files
committed
Fix some atomics effect models
1 parent 967ab56 commit 4efebe7

File tree

1 file changed

+52
-25
lines changed

1 file changed

+52
-25
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,13 +2333,17 @@ function abstract_eval_getglobal(interp::AbstractInterpreter, sv::AbsIntState, @
23332333
return CallMeta(Any, Union{UndefVarError, TypeError}, generic_getglobal_effects, NoCallInfo())
23342334
end
23352335

2336+
function merge_exct(cm::CallMeta, @nospecialize(exct))
2337+
if exct !== Bottom
2338+
cm = CallMeta(cm.rt, Union{cm.exct, exct}, Effects(cm.effects; nothrow=false), cm.info)
2339+
end
2340+
return cm
2341+
end
2342+
23362343
function abstract_eval_getglobal(interp::AbstractInterpreter, sv::AbsIntState, @nospecialize(M), @nospecialize(s), @nospecialize(order))
23372344
goe = global_order_exct(order, #=loading=#true, #=storing=#false)
23382345
cm = abstract_eval_getglobal(interp, sv, M, s)
2339-
if goe !== Bottom
2340-
cm = CallMeta(cm.rt, Union{cm.exct, goe}, Effects(cm.effects; nothrow=false), cm.info)
2341-
end
2342-
return cm
2346+
return merge_exct(cm, goe)
23432347
end
23442348

23452349
function abstract_eval_getglobal(interp::AbstractInterpreter, sv::AbsIntState, argtypes::Vector{Any})
@@ -2414,10 +2418,7 @@ end
24142418
function abstract_eval_setglobal!(interp::AbstractInterpreter, sv::AbsIntState, @nospecialize(M), @nospecialize(s), @nospecialize(v), @nospecialize(order))
24152419
goe = global_order_exct(order, #=loading=#false, #=storing=#true)
24162420
cm = abstract_eval_setglobal!(interp, sv, M, s, v)
2417-
if goe !== Bottom
2418-
cm = CallMeta(cm.rt, Union{cm.exct, goe}, Effects(cm.effects; nothrow=false), cm.info)
2419-
end
2420-
return cm
2421+
return merge_exct(cm, goe)
24212422
end
24222423

24232424
function abstract_eval_setglobal!(interp::AbstractInterpreter, sv::AbsIntState, argtypes::Vector{Any})
@@ -2432,6 +2433,25 @@ function abstract_eval_setglobal!(interp::AbstractInterpreter, sv::AbsIntState,
24322433
end
24332434
end
24342435

2436+
function abstract_eval_setglobalonce!(interp::AbstractInterpreter, sv::AbsIntState, argtypes::Vector{Any})
2437+
if length(argtypes) in (4, 5, 6)
2438+
cm = abstract_eval_setglobal!(interp, sv, argtypes[2], argtypes[3], argtypes[4])
2439+
if length(argtypes) >= 5
2440+
goe = global_order_exct(argtypes[5], #=loading=#true, #=storing=#true)
2441+
cm = merge_exct(cm, goe)
2442+
end
2443+
if length(argtypes) == 6
2444+
goe = global_order_exct(argtypes[6], #=loading=#true, #=storing=#false)
2445+
cm = merge_exct(cm, goe)
2446+
end
2447+
return CallMeta(Bool, cm.exct, cm.effects, cm.info)
2448+
elseif !isvarargtype(argtypes[end]) || length(argtypes) > 6
2449+
return CallMeta(Union{}, ArgumentError, EFFECTS_THROWS, NoCallInfo())
2450+
else
2451+
return CallMeta(Bool, Union{ArgumentError, TypeError, ErrorException, ConcurrencyViolationError}, setglobal!_effects, NoCallInfo())
2452+
end
2453+
end
2454+
24352455
function abstract_eval_replaceglobal!(interp::AbstractInterpreter, sv::AbsIntState, argtypes::Vector{Any})
24362456
if length(argtypes) in (5, 6, 7)
24372457
(M, s, x, v) = argtypes[2], argtypes[3], argtypes[4], argtypes[5]
@@ -2442,26 +2462,24 @@ function abstract_eval_replaceglobal!(interp::AbstractInterpreter, sv::AbsIntSta
24422462
if !(M isa Module && s isa Symbol)
24432463
return CallMeta(Union{}, TypeError, EFFECTS_THROWS, NoCallInfo())
24442464
end
2445-
partition = abstract_eval_binding_partition!(interp, g, sv)
2465+
partition = abstract_eval_binding_partition!(interp, GlobalRef(M, s), sv)
2466+
rte = abstract_eval_partition_load(interp, partition)
24462467
if binding_kind(partition) == BINDING_KIND_GLOBAL
24472468
T = partition_restriction(partition)
24482469
end
2449-
exct = global_assignment_binding_exct(partition, v)
2450-
sg = CallMeta(v, exct, Effects(setglobal!_effects, nothrow=exct===Bottom), NoCallInfo())
2470+
exct = Union{rte.exct, global_assignment_binding_exct(partition, v)}
2471+
effects = merge_effects(rte.effects, Effects(setglobal!_effects, nothrow=exct===Bottom))
2472+
sg = CallMeta(Any, exct, effects, NoCallInfo())
24512473
else
24522474
sg = abstract_eval_setglobal!(interp, sv, M, s, v)
24532475
end
24542476
if length(argtypes) >= 6
24552477
goe = global_order_exct(argtypes[6], #=loading=#true, #=storing=#true)
2456-
if goe !== Bottom
2457-
sg = CallMeta(sg.rt, Union{sg.exct, goe}, Effects(sg.effects; nothrow=false), sg.info)
2458-
end
2478+
sg = merge_exct(sg, goe)
24592479
end
24602480
if length(argtypes) == 7
24612481
goe = global_order_exct(argtypes[7], #=loading=#true, #=storing=#false)
2462-
if goe !== Bottom
2463-
sg = CallMeta(sg.rt, Union{sg.exct, goe}, Effects(sg.effects; nothrow=false), sg.info)
2464-
end
2482+
sg = merge_exct(sg, goe)
24652483
end
24662484
rt = T === nothing ?
24672485
ccall(:jl_apply_cmpswap_type, Any, (Any,), S) where S :
@@ -2510,20 +2528,26 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
25102528
elseif f === Core.setglobal!
25112529
return Future(abstract_eval_setglobal!(interp, sv, argtypes))
25122530
elseif f === Core.setglobalonce!
2513-
sg = abstract_eval_setglobal!(interp, sv, argtypes)
2514-
return Future(CallMeta(sg.rt === Bottom ? Bottom : Bool, sg.exct, sg.effects, sg.info))
2531+
return Future(abstract_eval_setglobalonce!(interp, sv, argtypes))
25152532
elseif f === Core.replaceglobal!
25162533
return Future(abstract_eval_replaceglobal!(interp, sv, argtypes))
25172534
elseif f === Core.getfield && args_are_actually_getglobal(argtypes)
25182535
return Future(abstract_eval_getglobal(interp, sv, argtypes))
25192536
elseif f === Core.isdefined && args_are_actually_getglobal(argtypes)
2520-
return Future(CallMeta(
2521-
abstract_eval_isdefined(
2537+
exct = Bottom
2538+
if length(argtypes) == 4
2539+
order = argtypes[4]
2540+
exct = global_order_exct(order, true, false)
2541+
if !(isa(order, Const) && get_atomic_order(order.val, true, false).x >= MEMORY_ORDER_UNORDERED.x)
2542+
exct = Union{exct, ConcurrencyViolationError}
2543+
end
2544+
end
2545+
return Future(merge_exct(CallMeta(abstract_eval_isdefined(
25222546
interp,
25232547
GlobalRef((argtypes[2]::Const).val,
25242548
(argtypes[3]::Const).val),
25252549
sv),
2526-
NoCallInfo()))
2550+
NoCallInfo()), exct))
25272551
elseif f === Core.get_binding_type
25282552
return Future(abstract_eval_get_binding_type(interp, sv, argtypes))
25292553
end
@@ -3312,9 +3336,7 @@ function abstract_eval_binding_partition!(interp::AbstractInterpreter, g::Global
33123336
return partition
33133337
end
33143338

3315-
function abstract_eval_globalref(interp::AbstractInterpreter, g::GlobalRef, sv::AbsIntState)
3316-
partition = abstract_eval_binding_partition!(interp, g, sv)
3317-
3339+
function abstract_eval_partition_load(interp::AbstractInterpreter, partition::Core.BindingPartition)
33183340
consistent = inaccessiblememonly = ALWAYS_FALSE
33193341
nothrow = false
33203342
generic_effects = Effects(EFFECTS_TOTAL; consistent, nothrow, inaccessiblememonly)
@@ -3346,6 +3368,11 @@ function abstract_eval_globalref(interp::AbstractInterpreter, g::GlobalRef, sv::
33463368
return RTEffects(rt, UndefVarError, generic_effects)
33473369
end
33483370

3371+
function abstract_eval_globalref(interp::AbstractInterpreter, g::GlobalRef, sv::AbsIntState)
3372+
partition = abstract_eval_binding_partition!(interp, g, sv)
3373+
return abstract_eval_partition_load(interp, partition)
3374+
end
3375+
33493376
function global_assignment_exct(interp::AbstractInterpreter, sv::AbsIntState, g::GlobalRef, @nospecialize(newty))
33503377
partition = abstract_eval_binding_partition!(interp, g, sv)
33513378
return global_assignment_binding_exct(partition, newty)

0 commit comments

Comments
 (0)