407
407
if isa (a1, DataType) && ! isabstracttype (a1)
408
408
if a1 === Module
409
409
hasintersect (widenconst (sym), Symbol) || return Bottom
410
- if isa (sym, Const) && isa (sym. val, Symbol) && isa (arg1, Const) &&
411
- isdefinedconst_globalref (GlobalRef (arg1. val:: Module , sym. val:: Symbol ))
412
- return Const (true )
413
- end
410
+ # isa(sym, Const) case intercepted in abstract interpretation
414
411
elseif isa (sym, Const)
415
412
val = sym. val
416
413
if isa (val, Symbol)
@@ -1160,7 +1157,9 @@ end
1160
1157
if isa (sv, Module)
1161
1158
setfield && return Bottom
1162
1159
if isa (nv, Symbol)
1163
- return abstract_eval_global (sv, nv)
1160
+ # In ordinary inference, this case is intercepted early and
1161
+ # re-routed to `getglobal`.
1162
+ return Any
1164
1163
end
1165
1164
return Bottom
1166
1165
end
@@ -1407,8 +1406,9 @@ end
1407
1406
elseif ff === Core. modifyglobal!
1408
1407
o = unwrapva (argtypes[2 ])
1409
1408
f = unwrapva (argtypes[3 ])
1410
- RT = modifyglobal!_tfunc (𝕃ᵢ, o, f, Any, Any, Symbol)
1411
- TF = getglobal_tfunc (𝕃ᵢ, o, f, Symbol)
1409
+ GT = abstract_eval_get_binding_type (interp, sv, o, f). rt
1410
+ RT = isa (GT, Const) ? Pair{GT. val, GT. val} : Pair
1411
+ TF = isa (GT, Const) ? GT. val : Any
1412
1412
elseif ff === Core. memoryrefmodify!
1413
1413
o = unwrapva (argtypes[2 ])
1414
1414
RT = memoryrefmodify!_tfunc (𝕃ᵢ, o, Any, Any, Symbol, Bool)
@@ -2277,20 +2277,6 @@ function _builtin_nothrow(𝕃::AbstractLattice, @nospecialize(f::Builtin), argt
2277
2277
elseif f === typeassert
2278
2278
na == 2 || return false
2279
2279
return typeassert_nothrow (𝕃, argtypes[1 ], argtypes[2 ])
2280
- elseif f === getglobal
2281
- if na == 2
2282
- return getglobal_nothrow (argtypes[1 ], argtypes[2 ])
2283
- elseif na == 3
2284
- return getglobal_nothrow (argtypes[1 ], argtypes[2 ], argtypes[3 ])
2285
- end
2286
- return false
2287
- elseif f === setglobal!
2288
- if na == 3
2289
- return setglobal!_nothrow (argtypes[1 ], argtypes[2 ], argtypes[3 ])
2290
- elseif na == 4
2291
- return setglobal!_nothrow (argtypes[1 ], argtypes[2 ], argtypes[3 ], argtypes[4 ])
2292
- end
2293
- return false
2294
2280
elseif f === Core. get_binding_type
2295
2281
na == 2 || return false
2296
2282
return get_binding_type_nothrow (𝕃, argtypes[1 ], argtypes[2 ])
@@ -2473,7 +2459,8 @@ function getfield_effects(𝕃::AbstractLattice, argtypes::Vector{Any}, @nospeci
2473
2459
end
2474
2460
end
2475
2461
if hasintersect (widenconst (obj), Module)
2476
- inaccessiblememonly = getglobal_effects (argtypes, rt). inaccessiblememonly
2462
+ # Modeled more precisely in abstract_eval_getglobal
2463
+ inaccessiblememonly = ALWAYS_FALSE
2477
2464
elseif is_mutation_free_argtype (obj)
2478
2465
inaccessiblememonly = ALWAYS_TRUE
2479
2466
else
@@ -2482,24 +2469,7 @@ function getfield_effects(𝕃::AbstractLattice, argtypes::Vector{Any}, @nospeci
2482
2469
return Effects (EFFECTS_TOTAL; consistent, nothrow, inaccessiblememonly, noub)
2483
2470
end
2484
2471
2485
- function getglobal_effects (argtypes:: Vector{Any} , @nospecialize (rt))
2486
- 2 ≤ length (argtypes) ≤ 3 || return EFFECTS_THROWS
2487
- consistent = inaccessiblememonly = ALWAYS_FALSE
2488
- nothrow = false
2489
- M, s = argtypes[1 ], argtypes[2 ]
2490
- if (length (argtypes) == 3 ? getglobal_nothrow (M, s, argtypes[3 ]) : getglobal_nothrow (M, s))
2491
- nothrow = true
2492
- # typeasserts below are already checked in `getglobal_nothrow`
2493
- Mval, sval = (M:: Const ). val:: Module , (s:: Const ). val:: Symbol
2494
- if isconst (Mval, sval)
2495
- consistent = ALWAYS_TRUE
2496
- if is_mutation_free_argtype (rt)
2497
- inaccessiblememonly = ALWAYS_TRUE
2498
- end
2499
- end
2500
- end
2501
- return Effects (EFFECTS_TOTAL; consistent, nothrow, inaccessiblememonly)
2502
- end
2472
+
2503
2473
2504
2474
"""
2505
2475
builtin_effects(𝕃::AbstractLattice, f::Builtin, argtypes::Vector{Any}, rt) -> Effects
@@ -2525,11 +2495,13 @@ function builtin_effects(𝕃::AbstractLattice, @nospecialize(f::Builtin), argty
2525
2495
if f === isdefined
2526
2496
return isdefined_effects (𝕃, argtypes)
2527
2497
elseif f === getglobal
2528
- return getglobal_effects (argtypes, rt)
2498
+ 2 ≤ length (argtypes) ≤ 3 || return EFFECTS_THROWS
2499
+ # Modeled more precisely in abstract_eval_getglobal
2500
+ return Effects (EFFECTS_TOTAL; consistent= ALWAYS_FALSE, nothrow= false , inaccessiblememonly= ALWAYS_FALSE)
2529
2501
elseif f === Core. get_binding_type
2530
2502
length (argtypes) == 2 || return EFFECTS_THROWS
2531
- effect_free = get_binding_type_effect_free (argtypes[ 1 ], argtypes[ 2 ]) ? ALWAYS_TRUE : ALWAYS_FALSE
2532
- return Effects (EFFECTS_TOTAL; effect_free)
2503
+ # Modeled more precisely in abstract_eval_get_binding_type
2504
+ return Effects (EFFECTS_TOTAL; effect_free= ALWAYS_FALSE )
2533
2505
elseif f === compilerbarrier
2534
2506
length (argtypes) == 2 || return Effects (EFFECTS_THROWS; consistent= ALWAYS_FALSE)
2535
2507
setting = argtypes[1 ]
@@ -3065,118 +3037,28 @@ function typename_static(@nospecialize(t))
3065
3037
return isType (t) ? _typename (t. parameters[1 ]) : Core. TypeName
3066
3038
end
3067
3039
3068
- function global_order_nothrow (@nospecialize (o), loading:: Bool , storing:: Bool )
3069
- o isa Const || return false
3040
+ function global_order_exct (@nospecialize (o), loading:: Bool , storing:: Bool )
3041
+ if ! (o isa Const)
3042
+ if o === Symbol
3043
+ return ConcurrencyViolationError
3044
+ elseif ! hasintersect (o, Symbol)
3045
+ return TypeError
3046
+ else
3047
+ return Union{ConcurrencyViolationError, TypeError}
3048
+ end
3049
+ end
3070
3050
sym = o. val
3071
3051
if sym isa Symbol
3072
3052
order = get_atomic_order (sym, loading, storing)
3073
- return order != = MEMORY_ORDER_INVALID && order != = MEMORY_ORDER_NOTATOMIC
3074
- end
3075
- return false
3076
- end
3077
- @nospecs function getglobal_nothrow (M, s, o)
3078
- global_order_nothrow (o, #= loading=# true , #= storing=# false ) || return false
3079
- return getglobal_nothrow (M, s)
3080
- end
3081
- @nospecs function getglobal_nothrow (M, s)
3082
- if M isa Const && s isa Const
3083
- M, s = M. val, s. val
3084
- if M isa Module && s isa Symbol
3085
- return isdefinedconst_globalref (GlobalRef (M, s))
3086
- end
3087
- end
3088
- return false
3089
- end
3090
- @nospecs function getglobal_tfunc (𝕃:: AbstractLattice , M, s, order= Symbol)
3091
- if M isa Const && s isa Const
3092
- M, s = M. val, s. val
3093
- if M isa Module && s isa Symbol
3094
- return abstract_eval_global (M, s)
3095
- end
3096
- return Bottom
3097
- elseif ! (hasintersect (widenconst (M), Module) && hasintersect (widenconst (s), Symbol))
3098
- return Bottom
3099
- end
3100
- T = get_binding_type_tfunc (𝕃, M, s)
3101
- T isa Const && return T. val
3102
- return Any
3103
- end
3104
- @nospecs function setglobal!_tfunc (𝕃:: AbstractLattice , M, s, v, order= Symbol)
3105
- if ! (hasintersect (widenconst (M), Module) && hasintersect (widenconst (s), Symbol))
3106
- return Bottom
3107
- end
3108
- return v
3109
- end
3110
- @nospecs function swapglobal!_tfunc (𝕃:: AbstractLattice , M, s, v, order= Symbol)
3111
- setglobal!_tfunc (𝕃, M, s, v) === Bottom && return Bottom
3112
- return getglobal_tfunc (𝕃, M, s)
3113
- end
3114
- @nospecs function modifyglobal!_tfunc (𝕃:: AbstractLattice , M, s, op, v, order= Symbol)
3115
- T = get_binding_type_tfunc (𝕃, M, s)
3116
- T === Bottom && return Bottom
3117
- T isa Const || return Pair
3118
- T = T. val
3119
- return Pair{T, T}
3120
- end
3121
- @nospecs function replaceglobal!_tfunc (𝕃:: AbstractLattice , M, s, x, v, success_order= Symbol, failure_order= Symbol)
3122
- v = setglobal!_tfunc (𝕃, M, s, v)
3123
- v === Bottom && return Bottom
3124
- T = get_binding_type_tfunc (𝕃, M, s)
3125
- T === Bottom && return Bottom
3126
- T isa Const || return ccall (:jl_apply_cmpswap_type , Any, (Any,), T) where T
3127
- T = T. val
3128
- return ccall (:jl_apply_cmpswap_type , Any, (Any,), T)
3129
- end
3130
- @nospecs function setglobalonce!_tfunc (𝕃:: AbstractLattice , M, s, v, success_order= Symbol, failure_order= Symbol)
3131
- setglobal!_tfunc (𝕃, M, s, v) === Bottom && return Bottom
3132
- return Bool
3133
- end
3134
-
3135
- add_tfunc (Core. getglobal, 2 , 3 , getglobal_tfunc, 1 )
3136
- add_tfunc (Core. setglobal!, 3 , 4 , setglobal!_tfunc, 3 )
3137
- add_tfunc (Core. swapglobal!, 3 , 4 , swapglobal!_tfunc, 3 )
3138
- add_tfunc (Core. modifyglobal!, 4 , 5 , modifyglobal!_tfunc, 3 )
3139
- add_tfunc (Core. replaceglobal!, 4 , 6 , replaceglobal!_tfunc, 3 )
3140
- add_tfunc (Core. setglobalonce!, 3 , 5 , setglobalonce!_tfunc, 3 )
3141
-
3142
- @nospecs function setglobal!_nothrow (M, s, newty, o)
3143
- global_order_nothrow (o, #= loading=# false , #= storing=# true ) || return false
3144
- return setglobal!_nothrow (M, s, newty)
3145
- end
3146
- @nospecs function setglobal!_nothrow (M, s, newty)
3147
- if M isa Const && s isa Const
3148
- M, s = M. val, s. val
3149
- if isa (M, Module) && isa (s, Symbol)
3150
- return global_assignment_nothrow (M, s, newty)
3151
- end
3152
- end
3153
- return false
3154
- end
3155
-
3156
- function global_assignment_nothrow (M:: Module , s:: Symbol , @nospecialize (newty))
3157
- if ! isconst (M, s)
3158
- ty = ccall (:jl_get_binding_type , Any, (Any, Any), M, s)
3159
- return ty isa Type && widenconst (newty) <: ty
3160
- end
3161
- return false
3162
- end
3163
-
3164
- @nospecs function get_binding_type_effect_free (M, s)
3165
- if M isa Const && s isa Const
3166
- M, s = M. val, s. val
3167
- if M isa Module && s isa Symbol
3168
- return ccall (:jl_get_binding_type , Any, (Any, Any), M, s) != = nothing
3053
+ if order != = MEMORY_ORDER_INVALID && order != = MEMORY_ORDER_NOTATOMIC
3054
+ return Union{}
3055
+ else
3056
+ return ConcurrencyViolationError
3169
3057
end
3058
+ else
3059
+ return TypeError
3170
3060
end
3171
- return false
3172
- end
3173
- @nospecs function get_binding_type_tfunc (𝕃:: AbstractLattice , M, s)
3174
- if get_binding_type_effect_free (M, s)
3175
- return Const (Core. get_binding_type ((M:: Const ). val:: Module , (s:: Const ). val:: Symbol ))
3176
- end
3177
- return Type
3178
3061
end
3179
- add_tfunc (Core. get_binding_type, 2 , 2 , get_binding_type_tfunc, 0 )
3180
3062
3181
3063
@nospecs function get_binding_type_nothrow (𝕃:: AbstractLattice , M, s)
3182
3064
⊑ = partialorder (𝕃)
0 commit comments