summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2023-04-28 10:21:32 +0200
committerBjörn Gustavsson <bjorn@erlang.org>2023-04-28 12:44:32 +0200
commitf9b1ee13b38c0f2b5d327e0d051e52cd5b2b0f17 (patch)
tree1158a16d8ffbac3c7792404eb8e915c5c3ffd571
parent86e6ebf531e2bd6222a7a29a422b704cd10a88be (diff)
downloaderlang-f9b1ee13b38c0f2b5d327e0d051e52cd5b2b0f17.tar.gz
Eliminate crash in beam_ssa_type
Closes #7179
-rw-r--r--lib/compiler/src/beam_call_types.erl17
-rw-r--r--lib/compiler/test/beam_type_SUITE.erl21
2 files changed, 31 insertions, 7 deletions
diff --git a/lib/compiler/src/beam_call_types.erl b/lib/compiler/src/beam_call_types.erl
index 8b9cb836fd..697566cecb 100644
--- a/lib/compiler/src/beam_call_types.erl
+++ b/lib/compiler/src/beam_call_types.erl
@@ -365,12 +365,19 @@ types(erlang, is_boolean, [Type]) ->
types(erlang, is_float, [Type]) ->
sub_unsafe_type_test(Type, #t_float{});
types(erlang, is_function, [Type, #t_integer{elements={Arity,Arity}}])
- when Arity >= 0, Arity =< ?MAX_FUNC_ARGS ->
+ when is_integer(Arity) ->
RetType =
- case meet(Type, #t_fun{arity=Arity}) of
- Type -> #t_atom{elements=[true]};
- none -> #t_atom{elements=[false]};
- _ -> beam_types:make_boolean()
+ if
+ Arity < 0 ->
+ none;
+ 0 =< Arity, Arity =< ?MAX_FUNC_ARGS ->
+ case meet(Type, #t_fun{arity=Arity}) of
+ Type -> #t_atom{elements=[true]};
+ none -> #t_atom{elements=[false]};
+ _ -> beam_types:make_boolean()
+ end;
+ Arity > ?MAX_FUNC_ARGS ->
+ #t_atom{elements=[false]}
end,
sub_unsafe(RetType, [any, any]);
types(erlang, is_function, [Type]) ->
diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl
index 6562b3228f..668bb64a37 100644
--- a/lib/compiler/test/beam_type_SUITE.erl
+++ b/lib/compiler/test/beam_type_SUITE.erl
@@ -29,7 +29,8 @@
container_subtraction/1,is_list_opt/1,connected_tuple_elements/1,
switch_fail_inference/1,failures/1,
cover_maps_functions/1,min_max_mixed_types/1,
- not_equal/1,infer_relops/1,binary_unit/1,premature_concretization/1]).
+ not_equal/1,infer_relops/1,binary_unit/1,premature_concretization/1,
+ funs/1]).
%% Force id/1 to return 'any'.
-export([id/1]).
@@ -71,7 +72,8 @@ groups() ->
not_equal,
infer_relops,
binary_unit,
- premature_concretization
+ premature_concretization,
+ funs
]}].
init_per_suite(Config) ->
@@ -1369,5 +1371,20 @@ pm_concretization_2(_, Tagged) -> {error, Tagged}.
pm_concretization_3(_) -> ok.
pm_concretization_4(_) -> ok.
+funs(_Config) ->
+ {'EXIT',{badarg,_}} = catch gh_7179(),
+ false = is_function(id(fun() -> ok end), 1024),
+
+ ok.
+
+%% GH-7179: The beam_ssa_type pass would crash.
+gh_7179() ->
+ << <<0>> || is_function([0 || <<_>> <= <<>>], -1),
+ [] <- [] >>.
+
+%%%
+%%% Common utilities.
+%%%
+
id(I) ->
I.