File 2017-dialyzer_dep-Eliminate-dependency-on-the-cerl_closur.patch of Package erlang
From 1bd4c8e989898a2edf365e4850350ff01bd31309 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Fri, 17 Sep 2021 08:22:32 +0200
Subject: [PATCH 17/20] dialyzer_dep: Eliminate dependency on the
cerl_closurean module
Copy the is_escape_op/2,3 and is_literal_op/2,3 functions from
cerl_closurean into dialyzer_dep.
---
lib/dialyzer/src/dialyzer_dep.erl | 68 +++++++++++++++++++++++++++++--
1 file changed, 64 insertions(+), 4 deletions(-)
diff --git a/lib/dialyzer/src/dialyzer_dep.erl b/lib/dialyzer/src/dialyzer_dep.erl
index f5885a8567..c565a0a612 100644
--- a/lib/dialyzer/src/dialyzer_dep.erl
+++ b/lib/dialyzer/src/dialyzer_dep.erl
@@ -279,7 +279,7 @@ remote_call(Tree, ArgFuns, State) ->
true ->
M1 = cerl:atom_val(M),
F1 = cerl:atom_val(F),
- Literal = cerl_closurean:is_literal_op(M1, F1, A),
+ Literal = is_literal_op(M1, F1, A),
case erl_bifs:is_pure(M1, F1, A) of
true ->
case Literal of
@@ -289,7 +289,7 @@ remote_call(Tree, ArgFuns, State) ->
{output(set__singleton(external)), state__add_esc(ArgFuns, State)}
end;
false ->
- State1 = case cerl_closurean:is_escape_op(M1, F1, A) of
+ State1 = case is_escape_op(M1, F1, A) of
true -> state__add_esc(ArgFuns, State);
false -> State
end,
@@ -303,15 +303,75 @@ remote_call(Tree, ArgFuns, State) ->
primop(Tree, ArgFuns, State) ->
F = cerl:atom_val(cerl:primop_name(Tree)),
A = length(cerl:primop_args(Tree)),
- State1 = case cerl_closurean:is_escape_op(F, A) of
+ State1 = case is_escape_op(F, A) of
true -> state__add_esc(ArgFuns, State);
false -> State
end,
- case cerl_closurean:is_literal_op(F, A) of
+ case is_literal_op(F, A) of
true -> {output(none), State1};
false -> {ArgFuns, State1}
end.
+%%------------------------------------------------------------
+
+%% Escape operators may let their arguments escape. Unless we know
+%% otherwise, and the function is not pure, we assume this is the case.
+%% Error-raising functions (fault/match_fail) are not considered as
+%% escapes (but throw/exit are). Zero-argument functions need not be
+%% listed.
+
+-spec is_escape_op(atom(), arity()) -> boolean().
+
+is_escape_op(match_fail, 1) -> false;
+is_escape_op(recv_wait_timeout, 1) -> false;
+is_escape_op(F, A) when is_atom(F), is_integer(A) -> true.
+
+-spec is_escape_op(atom(), atom(), arity()) -> boolean().
+
+is_escape_op(erlang, error, 1) -> false;
+is_escape_op(erlang, error, 2) -> false;
+is_escape_op(M, F, A) when is_atom(M), is_atom(F), is_integer(A) -> true.
+
+%% "Literal" operators will never return functional values even when
+%% found in their arguments. Unless we know otherwise, we assume this is
+%% not the case. (More functions can be added to this list, if needed
+%% for better precision. Note that the result of `term_to_binary' still
+%% contains an encoding of the closure.)
+
+-spec is_literal_op(atom(), arity()) -> boolean().
+
+is_literal_op(recv_wait_timeout, 1) -> true;
+is_literal_op(match_fail, 1) -> true;
+is_literal_op(F, A) when is_atom(F), is_integer(A) -> false.
+
+-spec is_literal_op(atom(), atom(), arity()) -> boolean().
+
+is_literal_op(erlang, '+', 2) -> true;
+is_literal_op(erlang, '-', 2) -> true;
+is_literal_op(erlang, '*', 2) -> true;
+is_literal_op(erlang, '/', 2) -> true;
+is_literal_op(erlang, '=:=', 2) -> true;
+is_literal_op(erlang, '==', 2) -> true;
+is_literal_op(erlang, '=/=', 2) -> true;
+is_literal_op(erlang, '/=', 2) -> true;
+is_literal_op(erlang, '<', 2) -> true;
+is_literal_op(erlang, '=<', 2) -> true;
+is_literal_op(erlang, '>', 2) -> true;
+is_literal_op(erlang, '>=', 2) -> true;
+is_literal_op(erlang, 'and', 2) -> true;
+is_literal_op(erlang, 'or', 2) -> true;
+is_literal_op(erlang, 'not', 1) -> true;
+is_literal_op(erlang, length, 1) -> true;
+is_literal_op(erlang, size, 1) -> true;
+is_literal_op(erlang, fun_info, 1) -> true;
+is_literal_op(erlang, fun_info, 2) -> true;
+is_literal_op(erlang, fun_to_list, 1) -> true;
+is_literal_op(erlang, throw, 1) -> true;
+is_literal_op(erlang, exit, 1) -> true;
+is_literal_op(erlang, error, 1) -> true;
+is_literal_op(erlang, error, 2) -> true;
+is_literal_op(M, F, A) when is_atom(M), is_atom(F), is_integer(A) -> false.
+
%%------------------------------------------------------------
%% Set
%%
--
2.31.1