Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #33768, inference of _apply with strange argument list lengths #33832

Merged
merged 1 commit into from
Nov 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions base/compiler/abstractinterpretation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -639,11 +639,33 @@ function pure_eval_call(@nospecialize(f), argtypes::Vector{Any}, @nospecialize(a
end
end

function argtype_by_index(argtypes::Vector{Any}, i::Int)
n = length(argtypes)
if isvarargtype(argtypes[n])
return i >= n ? unwrapva(argtypes[n]) : argtypes[i]
else
return i > n ? Bottom : argtypes[i]
end
end

function argtype_tail(argtypes::Vector{Any}, i::Int)
n = length(argtypes)
if isvarargtype(argtypes[n]) && i > n
i = n
end
return argtypes[i:n]
end

function abstract_call(@nospecialize(f), fargs::Union{Nothing,Vector{Any}}, argtypes::Vector{Any}, vtypes::VarTable, sv::InferenceState, max_methods = sv.params.MAX_METHODS)
if f === _apply
return abstract_apply(nothing, argtypes[2], argtypes[3:end], vtypes, sv, max_methods)
ft = argtype_by_index(argtypes, 2)
ft === Bottom && return Bottom
return abstract_apply(nothing, ft, argtype_tail(argtypes, 3), vtypes, sv, max_methods)
elseif f === _apply_iterate
return abstract_apply(argtypes[2], argtypes[3], argtypes[4:end], vtypes, sv, max_methods)
itft = argtype_by_index(argtypes, 2)
ft = argtype_by_index(argtypes, 3)
(itft === Bottom || ft === Bottom) && return Bottom
return abstract_apply(itft, ft, argtype_tail(argtypes, 4), vtypes, sv, max_methods)
end

la = length(argtypes)
Expand Down
3 changes: 3 additions & 0 deletions base/compiler/ssair/inlining.jl
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,9 @@ function inline_apply!(ir::IRCode, idx::Int, sig::Signature, params::Params)
while sig.f === Core._apply || sig.f === Core._apply_iterate
arg_start = sig.f === Core._apply ? 2 : 3
atypes = sig.atypes
if arg_start > length(atypes)
return nothing
end
# Try to figure out the signature of the function being called
# and if rewrite_apply_exprargs can deal with this form
for i = (arg_start + 1):length(atypes)
Expand Down
3 changes: 2 additions & 1 deletion src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,6 @@ static jl_function_t *jl_iterate_func JL_GLOBALLY_ROOTED;

static jl_value_t *do_apply(jl_value_t *F, jl_value_t **args, uint32_t nargs, jl_value_t *iterate)
{
JL_NARGSV(apply, 1);
jl_function_t *f = args[0];
if (nargs == 2) {
// some common simple cases
Expand Down Expand Up @@ -634,11 +633,13 @@ static jl_value_t *do_apply(jl_value_t *F, jl_value_t **args, uint32_t nargs, jl

JL_CALLABLE(jl_f__apply_iterate)
{
JL_NARGSV(_apply_iterate, 2);
return do_apply(F, args+1, nargs-1, args[0]);
}

JL_CALLABLE(jl_f__apply)
{
JL_NARGSV(_apply, 1);
return do_apply(F, args, nargs, NULL);
}

Expand Down
18 changes: 18 additions & 0 deletions test/compiler/inference.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2464,3 +2464,21 @@ let N = TypeVar(:N)
Core.Compiler.PartialTypeVar(N, true, true),
Core.Compiler.Const(Any)], Type{Tuple{Vararg{Any,N}}})
end

# issue #33768
function f33768()
Core._apply()
end
function g33768()
a = Any[iterate, tuple, (1,)]
Core._apply_iterate(a...)
end
function h33768()
Core._apply_iterate()
end
@test_throws ArgumentError f33768()
@test Base.return_types(f33768, ()) == Any[Union{}]
@test g33768() === (1,)
@test Base.return_types(g33768, ()) == Any[Any]
@test_throws ArgumentError h33768()
@test Base.return_types(h33768, ()) == Any[Union{}]