Skip to content

Commit

Permalink
Fix #12612
Browse files Browse the repository at this point in the history
Throw an error when `call` is not a generic function for the fallback case
Do not panic in type inference if call is not defined
Add generic function assertion in jl_apply_generic
  • Loading branch information
yuyichao committed Aug 17, 2015
1 parent 72431c5 commit c0794f5
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 11 deletions.
5 changes: 4 additions & 1 deletion base/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,10 @@ function abstract_call(f, fargs, argtypes::Vector{Any}, vtypes, sv::StaticVarInf
# TODO: call() case
return Any
end
if !isa(f,Function) && !isa(f,IntrinsicFunction) && _iisdefined(:call)
if !isa(f,Function) && !isa(f,IntrinsicFunction)
if !_iisdefined(:call)
return Any
end
call_func = _ieval(:call)
if isa(call_func,Function)
return abstract_call(call_func, e.args,
Expand Down
25 changes: 16 additions & 9 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2614,7 +2614,7 @@ static Value *emit_call(jl_value_t **args, size_t arglen, jl_codectx_t *ctx, jl_
Value *r = emit_known_call((jl_value_t*)f, args-1, nargs+1, ctx, &theFptr, &f, expr);
assert(r == NULL); (void) r;
if (theFptr == NULL) {
just_emit_error("\"call\" is not a function", ctx);
just_emit_error("\"call\" is not a generic function", ctx);
result = UndefValue::get(jl_pvalue_llvmt);
}
else {
Expand Down Expand Up @@ -2688,17 +2688,24 @@ static Value *emit_call(jl_value_t **args, size_t arglen, jl_codectx_t *ctx, jl_
builder.SetInsertPoint(elseBB1);
// not function
myargs = emit_temp_slot(argStart, ctx);
jl_value_t *call_func = (jl_value_t*)jl_module_call_func(ctx->module);
Value *r2;
if (!jl_is_gf(call_func)) {
just_emit_error("\"call\" is not a generic function", ctx);
r2 = UndefValue::get(jl_pvalue_llvmt);
} else {
#ifdef LLVM37
Value *r2 = builder.CreateCall(prepare_call(jlapplygeneric_func),
{literal_pointer_val((jl_value_t*)jl_module_call_func(ctx->module)),
myargs,
ConstantInt::get(T_int32,nargs+1)});
r2 = builder.CreateCall(prepare_call(jlapplygeneric_func),
{literal_pointer_val(call_func),
myargs,
ConstantInt::get(T_int32, nargs + 1)});
#else
Value *r2 = builder.CreateCall3(prepare_call(jlapplygeneric_func),
literal_pointer_val((jl_value_t*)jl_module_call_func(ctx->module)),
myargs,
ConstantInt::get(T_int32,nargs+1));
r2 = builder.CreateCall3(prepare_call(jlapplygeneric_func),
literal_pointer_val(call_func),
myargs,
ConstantInt::get(T_int32, nargs + 1));
#endif
}
builder.CreateBr(mergeBB1);
ctx->f->getBasicBlockList().push_back(mergeBB1);
builder.SetInsertPoint(mergeBB1);
Expand Down
1 change: 1 addition & 0 deletions src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1611,6 +1611,7 @@ static void show_call(jl_value_t *F, jl_value_t **args, uint32_t nargs)

JL_CALLABLE(jl_apply_generic)
{
assert(jl_is_gf(F));
jl_methtable_t *mt = jl_gf_mtable(F);
#ifdef JL_GF_PROFILE
mt->ncalls++;
Expand Down
2 changes: 1 addition & 1 deletion src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ jl_function_t *jl_module_call_func(jl_module_t *m)
{
if (m->call_func == NULL) {
jl_function_t *cf = (jl_function_t*)jl_get_global(m, call_sym);
if (cf == NULL || !jl_is_function(cf))
if (cf == NULL || !jl_is_function(cf) || !jl_is_gf(cf))
cf = jl_bottom_func;
m->call_func = cf;
}
Expand Down
15 changes: 15 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3230,3 +3230,18 @@ end

@test @inferred(MyColors.myeltype(MyColors.RGB{Float32})) == Float32
@test @inferred(MyColors.myeltype(MyColors.RGB)) == Any

# issue #12612 (handle the case when `call` is not defined)
Main.eval(:(type Foo12612 end))

baremodule A12612
import Main: Foo12612
f1() = Foo12612()
f2() = Main.Foo12612()
end

## Don't panic in type inference if call is not defined
code_typed(A12612.f1, Tuple{})
code_typed(A12612.f2, Tuple{})
@test_throws ErrorException A12612.f1()
@test_throws ErrorException A12612.f2()

0 comments on commit c0794f5

Please sign in to comment.