diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index d4e4afdb8407b..dd156ae338058 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -2046,13 +2046,30 @@ function abstract_finalizer(interp::AbstractInterpreter, argtypes::Vector{Any}, return CallMeta(Nothing, Any, Effects(), NoCallInfo()) end +function abstract_throw(interp::AbstractInterpreter, argtypes::Vector{Any}, ::AbsIntState) + na = length(argtypes) + 𝕃ᵢ = typeinf_lattice(interp) + if na == 2 + argtype2 = argtypes[2] + if isvarargtype(argtype2) + exct = tmerge(𝕃ᵢ, unwrapva(argtype2), ArgumentError) + else + exct = argtype2 + end + elseif na == 3 && isvarargtype(argtypes[3]) + exct = tmerge(𝕃ᵢ, argtypes[2], ArgumentError) + else + exct = ArgumentError + end + return CallMeta(Union{}, exct, EFFECTS_THROWS, NoCallInfo()) +end + # call where the function is known exactly function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), arginfo::ArgInfo, si::StmtInfo, sv::AbsIntState, max_methods::Int = get_max_methods(interp, f, sv)) (; fargs, argtypes) = arginfo la = length(argtypes) - 𝕃ᵢ = typeinf_lattice(interp) if isa(f, Builtin) if f === _apply_iterate @@ -2066,19 +2083,7 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f), elseif f === applicable return abstract_applicable(interp, argtypes, sv, max_methods) elseif f === throw - if la == 2 - arg2 = argtypes[2] - if isvarargtype(arg2) - exct = tmerge(𝕃ᵢ, unwrapva(argtypes[2]), ArgumentError) - else - exct = arg2 - end - elseif la == 3 && isvarargtype(argtypes[3]) - exct = tmerge(𝕃ᵢ, argtypes[2], ArgumentError) - else - exct = ArgumentError - end - return CallMeta(Union{}, exct, EFFECTS_THROWS, NoCallInfo()) + return abstract_throw(interp, argtypes, sv) end rt = abstract_call_builtin(interp, f, arginfo, sv) ft = popfirst!(argtypes)