Skip to content

Commit 47b975c

Browse files
topolarityKristofferC
authored andcommitted
builtins: add Core.throw_methoderror (#55705)
This allows us to simulate/mark calls that are known-to-fail. Required for #54972
1 parent 7b46791 commit 47b975c

File tree

8 files changed

+32
-4
lines changed

8 files changed

+32
-4
lines changed

base/compiler/abstractinterpretation.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2226,6 +2226,17 @@ function abstract_throw(interp::AbstractInterpreter, argtypes::Vector{Any}, ::Ab
22262226
return CallMeta(Union{}, exct, EFFECTS_THROWS, NoCallInfo())
22272227
end
22282228

2229+
function abstract_throw_methoderror(interp::AbstractInterpreter, argtypes::Vector{Any}, ::AbsIntState)
2230+
exct = if length(argtypes) == 1
2231+
ArgumentError
2232+
elseif !isvarargtype(argtypes[2])
2233+
MethodError
2234+
else
2235+
tmerge(𝕃ᵢ, MethodError, ArgumentError)
2236+
end
2237+
return CallMeta(Union{}, exct, EFFECTS_THROWS, NoCallInfo())
2238+
end
2239+
22292240
# call where the function is known exactly
22302241
function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
22312242
arginfo::ArgInfo, si::StmtInfo, sv::AbsIntState,
@@ -2246,6 +2257,8 @@ function abstract_call_known(interp::AbstractInterpreter, @nospecialize(f),
22462257
return abstract_applicable(interp, argtypes, sv, max_methods)
22472258
elseif f === throw
22482259
return abstract_throw(interp, argtypes, sv)
2260+
elseif f === Core.throw_methoderror
2261+
return abstract_throw_methoderror(interp, argtypes, sv)
22492262
end
22502263
rt = abstract_call_builtin(interp, f, arginfo, sv)
22512264
ft = popfirst!(argtypes)

base/compiler/ssair/EscapeAnalysis/EscapeAnalysis.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,6 +1213,7 @@ escape_builtin!(::typeof(Core.donotdelete), _...) = false
12131213
# not really safe, but `ThrownEscape` will be imposed later
12141214
escape_builtin!(::typeof(isdefined), _...) = false
12151215
escape_builtin!(::typeof(throw), _...) = false
1216+
escape_builtin!(::typeof(Core.throw_methoderror), _...) = false
12161217

12171218
function escape_builtin!(::typeof(ifelse), astate::AnalysisState, pc::Int, args::Vector{Any})
12181219
length(args) == 4 || return false

base/compiler/tfuncs.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ function add_tfunc(@nospecialize(f::Builtin), minarg::Int, maxarg::Int, @nospeci
8989
end
9090

9191
add_tfunc(throw, 1, 1, @nospecs((𝕃::AbstractLattice, x)->Bottom), 0)
92+
add_tfunc(Core.throw_methoderror, 1, INT_INF, @nospecs((𝕃::AbstractLattice, x)->Bottom), 0)
9293

9394
# the inverse of typeof_tfunc
9495
# returns (type, isexact, isconcrete, istype)
@@ -2313,6 +2314,7 @@ const _CONSISTENT_BUILTINS = Any[
23132314
(<:),
23142315
typeassert,
23152316
throw,
2317+
Core.throw_methoderror,
23162318
setfield!,
23172319
donotdelete
23182320
]
@@ -2335,6 +2337,7 @@ const _EFFECT_FREE_BUILTINS = [
23352337
(<:),
23362338
typeassert,
23372339
throw,
2340+
Core.throw_methoderror,
23382341
getglobal,
23392342
compilerbarrier,
23402343
]
@@ -2350,6 +2353,7 @@ const _INACCESSIBLEMEM_BUILTINS = Any[
23502353
isa,
23512354
nfields,
23522355
throw,
2356+
Core.throw_methoderror,
23532357
tuple,
23542358
typeassert,
23552359
typeof,

src/builtin_proto.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ DECLARE_BUILTIN(svec);
6969
DECLARE_BUILTIN(swapfield);
7070
DECLARE_BUILTIN(swapglobal);
7171
DECLARE_BUILTIN(throw);
72+
DECLARE_BUILTIN(throw_methoderror);
7273
DECLARE_BUILTIN(tuple);
7374
DECLARE_BUILTIN(typeassert);
7475
DECLARE_BUILTIN(typeof);

src/builtins.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,14 @@ JL_CALLABLE(jl_f_throw)
580580
return jl_nothing;
581581
}
582582

583+
JL_CALLABLE(jl_f_throw_methoderror)
584+
{
585+
JL_NARGSV(throw_methoderror, 1);
586+
size_t world = jl_get_tls_world_age();
587+
jl_method_error(args[0], &args[1], nargs, world);
588+
return jl_nothing;
589+
}
590+
583591
JL_CALLABLE(jl_f_ifelse)
584592
{
585593
JL_NARGS(ifelse, 3, 3);
@@ -2437,6 +2445,7 @@ void jl_init_primitives(void) JL_GC_DISABLED
24372445
add_builtin_func("_compute_sparams", jl_f__compute_sparams);
24382446
add_builtin_func("_svec_ref", jl_f__svec_ref);
24392447
add_builtin_func("current_scope", jl_f_current_scope);
2448+
add_builtin_func("throw_methoderror", jl_f_throw_methoderror);
24402449

24412450
// builtin types
24422451
add_builtin("Any", (jl_value_t*)jl_any_type);

src/gf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,7 +2335,7 @@ JL_DLLEXPORT void jl_method_table_insert(jl_methtable_t *mt, jl_method_t *method
23352335
JL_GC_POP();
23362336
}
23372337

2338-
static void JL_NORETURN jl_method_error_bare(jl_function_t *f, jl_value_t *args, size_t world)
2338+
static void JL_NORETURN jl_method_error_bare(jl_value_t *f, jl_value_t *args, size_t world)
23392339
{
23402340
if (jl_methoderror_type) {
23412341
jl_value_t *e = jl_new_struct_uninit(jl_methoderror_type);
@@ -2360,7 +2360,7 @@ static void JL_NORETURN jl_method_error_bare(jl_function_t *f, jl_value_t *args,
23602360
// not reached
23612361
}
23622362

2363-
void JL_NORETURN jl_method_error(jl_function_t *f, jl_value_t **args, size_t na, size_t world)
2363+
void JL_NORETURN jl_method_error(jl_value_t *f, jl_value_t **args, size_t na, size_t world)
23642364
{
23652365
jl_value_t *argtup = jl_f_tuple(NULL, args, na - 1);
23662366
JL_GC_PUSH1(&argtup);

src/julia_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ int jl_valid_type_param(jl_value_t *v);
705705

706706
JL_DLLEXPORT jl_value_t *jl_apply_2va(jl_value_t *f, jl_value_t **args, uint32_t nargs);
707707

708-
void JL_NORETURN jl_method_error(jl_function_t *f, jl_value_t **args, size_t na, size_t world);
708+
void JL_NORETURN jl_method_error(jl_value_t *F, jl_value_t **args, size_t na, size_t world);
709709
JL_DLLEXPORT jl_value_t *jl_get_exceptionf(jl_datatype_t *exception_type, const char *fmt, ...);
710710

711711
JL_DLLEXPORT void jl_typeassert(jl_value_t *x, jl_value_t *t);

src/staticdata.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ static htable_t relocatable_ext_cis;
497497
// (reverse of fptr_to_id)
498498
// This is a manually constructed dual of the fvars array, which would be produced by codegen for Julia code, for C.
499499
static const jl_fptr_args_t id_to_fptrs[] = {
500-
&jl_f_throw, &jl_f_is, &jl_f_typeof, &jl_f_issubtype, &jl_f_isa,
500+
&jl_f_throw, &jl_f_throw_methoderror, &jl_f_is, &jl_f_typeof, &jl_f_issubtype, &jl_f_isa,
501501
&jl_f_typeassert, &jl_f__apply_iterate, &jl_f__apply_pure,
502502
&jl_f__call_latest, &jl_f__call_in_world, &jl_f__call_in_world_total, &jl_f_isdefined,
503503
&jl_f_tuple, &jl_f_svec, &jl_f_intrinsic_call,

0 commit comments

Comments
 (0)