Skip to content

Commit 35729d9

Browse files
authored
inference: handle cases where :the_exception is used independently (JuliaLang#56836)
`Expr(:the_exception)` is handled by the interpreter in all cases, however, inference assumes it is only used within frames containing `try/catch`. This commit corrects that assumption.
1 parent 2ed1a41 commit 35729d9

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

Compiler/src/abstractinterpretation.jl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3240,8 +3240,16 @@ function abstract_eval_throw_undef_if_not(interp::AbstractInterpreter, e::Expr,
32403240
end
32413241

32423242
function abstract_eval_the_exception(::AbstractInterpreter, sv::InferenceState)
3243-
(;handlers, handler_at) = sv.handler_info::HandlerInfo
3244-
return the_exception_info(handlers[handler_at[sv.currpc][2]].exct)
3243+
(;handler_info) = sv
3244+
if handler_info === nothing
3245+
return the_exception_info(Any)
3246+
end
3247+
(;handlers, handler_at) = handler_info
3248+
handler_id = handler_at[sv.currpc][2]
3249+
if handler_id === 0
3250+
return the_exception_info(Any)
3251+
end
3252+
return the_exception_info(handlers[handler_id].exct)
32453253
end
32463254
abstract_eval_the_exception(::AbstractInterpreter, ::IRInterpretationState) = the_exception_info(Any)
32473255
the_exception_info(@nospecialize t) = RTEffects(t, Union{}, Effects(EFFECTS_TOTAL; consistent=ALWAYS_FALSE))

Compiler/test/inference.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6125,3 +6125,17 @@ function func_swapglobal!_must_throw(x)
61256125
end
61266126
@test Base.infer_return_type(func_swapglobal!_must_throw, (Int,); interp=SwapGlobalInterp()) === Union{}
61276127
@test !Compiler.is_effect_free(Base.infer_effects(func_swapglobal!_must_throw, (Int,); interp=SwapGlobalInterp()) )
6128+
6129+
@eval get_exception() = $(Expr(:the_exception))
6130+
@test Base.infer_return_type() do
6131+
get_exception()
6132+
end <: Any
6133+
@test @eval Base.infer_return_type((Float64,)) do x
6134+
out = $(Expr(:the_exception))
6135+
try
6136+
out = sin(x)
6137+
catch
6138+
out = $(Expr(:the_exception))
6139+
end
6140+
return out
6141+
end == Union{Float64,DomainError}

0 commit comments

Comments
 (0)