diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index 27b6e33c94918..62691e0a74639 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -1887,18 +1887,21 @@ function abstract_eval_cfunction(interp::AbstractInterpreter, e::Expr, vtypes::V end function abstract_eval_value_expr(interp::AbstractInterpreter, e::Expr, vtypes::VarTable, sv::InferenceState) - if e.head === :static_parameter + head = e.head + if head === :static_parameter n = e.args[1]::Int t = Any if 1 <= n <= length(sv.sptypes) t = sv.sptypes[n] end return t - elseif e.head === :boundscheck + elseif head === :boundscheck return Bool - else + elseif head === :the_exception + tristate_merge!(sv, Effects(EFFECTS_TOTAL; consistent=ALWAYS_FALSE)) return Any end + return Any end function abstract_eval_special_value(interp::AbstractInterpreter, @nospecialize(e), vtypes::VarTable, sv::InferenceState) diff --git a/test/compiler/effects.jl b/test/compiler/effects.jl index b0486968d473d..7ca2e5a03cfa7 100644 --- a/test/compiler/effects.jl +++ b/test/compiler/effects.jl @@ -60,6 +60,50 @@ end |> !Core.Compiler.is_consistent return nothing end |> Core.Compiler.is_foldable +# :the_exception expression should taint :consistent-cy +global inconsistent_var::Int = 42 +function throw_inconsistent() # this is still :consistent + throw(inconsistent_var) +end +function catch_inconsistent() + try + throw_inconsistent() + catch err + err + end +end +@test !Core.Compiler.is_consistent(Base.infer_effects(catch_inconsistent)) +cache_inconsistent() = catch_inconsistent() +function compare_inconsistent() + a = cache_inconsistent() + global inconsistent_var = 0 + b = cache_inconsistent() + global inconsistent_var = 42 + return a === b +end +@test !compare_inconsistent() +# return type information shouldn't be able to refine it also +function catch_inconsistent(x::T) where T + v = x + try + throw_inconsistent() + catch err + v = err::T + end + return v +end +@test !Core.Compiler.is_consistent(Base.infer_effects(catch_inconsistent, (Int,))) +cache_inconsistent(x) = catch_inconsistent(x) +function compare_inconsistent(x::T) where T + x = one(T) + a = cache_inconsistent(x) + global inconsistent_var = 0 + b = cache_inconsistent(x) + global inconsistent_var = 42 + return a === b +end +@test !compare_inconsistent(3) + # effects propagation for `Core.invoke` calls # https://github.com/JuliaLang/julia/issues/44763 global x44763::Int = 0