diff --git a/src/codegen.cpp b/src/codegen.cpp index 42df3e88ff459..77a1c93507116 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3105,6 +3105,7 @@ static jl_cgval_t emit_call(jl_value_t **args, size_t arglen, jl_codectx_t *ctx, } else { theF = literal_pointer_val((jl_value_t*)f); + jl_add_linfo_root(ctx->linfo, (jl_value_t*)f); result = emit_call_function_object(f, theF, theFptr, true, args-1, nargs+1, ctx); } } @@ -3132,6 +3133,7 @@ static jl_cgval_t emit_call(jl_value_t **args, size_t arglen, jl_codectx_t *ctx, } else { theF = literal_pointer_val((jl_value_t*)f); + jl_add_linfo_root(ctx->linfo, (jl_value_t*)f); } result = emit_call_function_object(f, theF, theFptr, specialized, args, nargs, ctx); } diff --git a/test/core.jl b/test/core.jl index 65004af73ca65..d1f5ad1594d6e 100644 --- a/test/core.jl +++ b/test/core.jl @@ -3543,3 +3543,37 @@ end # issue #14339 f14339{T<:Union{}}(x::T, y::T) = 0 @test_throws MethodError f14339(1, 2) + +# Make sure jlcall objects are rooted +# PR #14301 +module JLCall14301 + +# Define f +f() = 1 + +let i = Any[[1.23], [2.34]] + # f() with capture variables + # Intentionally type unstable so that the dynamic dispatch will + # read the corrupted tag if the object is incorrectly GC'd. + global f() = i[1][1] * i[2][1] +end + +# Another function that use f() +g() = f() * 100 +# Compile it +g() + +let i = 9.0 + # Override f() + global f() = i + 1 +end + +# Make sure the old f() method is GC'd if it was not rooted properly +gc() +gc() +gc() + +# Run again. +g() + +end