summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2023-05-03 13:52:45 +0200
committerBjörn Gustavsson <bjorn@erlang.org>2023-05-03 14:09:35 +0200
commit132fa15545d9f49ebcaa4abf99f3754df6efa868 (patch)
tree3c684c22a2135f4ff201160ad74a23ce547b0555 /lib
parent24211242b21aa8ff6d2691c898c162f9bd3d19d1 (diff)
downloaderlang-132fa15545d9f49ebcaa4abf99f3754df6efa868.tar.gz
Eliminate crash in beam_ssa_type
Closes #7197
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/beam_call_types.erl39
-rw-r--r--lib/compiler/test/beam_type_SUITE.erl10
2 files changed, 34 insertions, 15 deletions
diff --git a/lib/compiler/src/beam_call_types.erl b/lib/compiler/src/beam_call_types.erl
index 697566cecb..4324080098 100644
--- a/lib/compiler/src/beam_call_types.erl
+++ b/lib/compiler/src/beam_call_types.erl
@@ -364,21 +364,30 @@ types(erlang, is_boolean, [Type]) ->
end;
types(erlang, is_float, [Type]) ->
sub_unsafe_type_test(Type, #t_float{});
-types(erlang, is_function, [Type, #t_integer{elements={Arity,Arity}}])
- when is_integer(Arity) ->
- RetType =
- 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,
+types(erlang, is_function, [Type, ArityType]) ->
+ RetType = case meet(ArityType, #t_integer{}) of
+ none ->
+ none;
+ #t_integer{elements={Arity,Arity}}
+ when is_integer(Arity) ->
+ 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;
+ #t_integer{} ->
+ case meet(Type, #t_fun{}) of
+ none -> #t_atom{elements=[false]};
+ _ -> beam_types:make_boolean()
+ end
+ end,
sub_unsafe(RetType, [any, any]);
types(erlang, is_function, [Type]) ->
sub_unsafe_type_test(Type, #t_fun{});
diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl
index 18a29f2643..9c5fbc2e69 100644
--- a/lib/compiler/test/beam_type_SUITE.erl
+++ b/lib/compiler/test/beam_type_SUITE.erl
@@ -1410,6 +1410,8 @@ funs(_Config) ->
{'EXIT',{badarg,_}} = catch gh_7179(),
false = is_function(id(fun() -> ok end), 1024),
+ {'EXIT',{badarg,_}} = catch gh_7197(),
+
ok.
%% GH-7179: The beam_ssa_type pass would crash.
@@ -1417,6 +1419,14 @@ gh_7179() ->
<< <<0>> || is_function([0 || <<_>> <= <<>>], -1),
[] <- [] >>.
+%% GH-7197: The beam_ssa_type pass would crash.
+gh_7197() ->
+ [0 || is_function([ok || <<_>> <= <<>>], get_keys()),
+ fun (_) ->
+ ok
+ end].
+
+
%%%
%%% Common utilities.
%%%