aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer
diff options
context:
space:
mode:
authorZandra <[email protected]>2015-12-28 11:55:48 +0100
committerZandra <[email protected]>2015-12-28 11:55:48 +0100
commit60d310117c005d6a05dcfc729b79a174b44e5370 (patch)
tree8aa896e5bc58ab950e0a4c7dfb5eb3032614db0c /lib/dialyzer
parentfc7eb7da8b9ccbc883f2001cf14021da8c85da4d (diff)
parent33ddd3f0699cbb4aa9aea2ec7fcf690d5c498c53 (diff)
downloadotp-60d310117c005d6a05dcfc729b79a174b44e5370.tar.gz
otp-60d310117c005d6a05dcfc729b79a174b44e5370.tar.bz2
otp-60d310117c005d6a05dcfc729b79a174b44e5370.zip
Merge branch 'lucafavatella/dialyzer-fun-call' into maint
* lucafavatella/dialyzer-fun-call: Teach Dialyzer call to funs `M:F/A` (literal M, F, A) OTP-13217
Diffstat (limited to 'lib/dialyzer')
-rw-r--r--lib/dialyzer/src/dialyzer_analysis_callgraph.erl22
-rw-r--r--lib/dialyzer/src/dialyzer_callgraph.erl27
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/fun_arity2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/non_existing1
4 files changed, 50 insertions, 2 deletions
diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
index c57a22129c..826ac51775 100644
--- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
@@ -624,6 +624,28 @@ find_call_file_and_line(Tree, MFA) ->
MFA ->
Ann = cerl:get_ann(SubTree),
[{get_file(Ann), get_line(Ann)}|Acc];
+ {erlang, make_fun, 3} ->
+ [CA1, CA2, CA3] = cerl:call_args(SubTree),
+ case
+ cerl:is_c_atom(CA1) andalso
+ cerl:is_c_atom(CA2) andalso
+ cerl:is_c_int(CA3)
+ of
+ true ->
+ case
+ {cerl:concrete(CA1),
+ cerl:concrete(CA2),
+ cerl:concrete(CA3)}
+ of
+ MFA ->
+ Ann = cerl:get_ann(SubTree),
+ [{get_file(Ann), get_line(Ann)}|Acc];
+ _ ->
+ Acc
+ end;
+ false ->
+ Acc
+ end;
_ -> Acc
end;
false -> Acc
diff --git a/lib/dialyzer/src/dialyzer_callgraph.erl b/lib/dialyzer/src/dialyzer_callgraph.erl
index a1cd2015ca..9e53e171c0 100644
--- a/lib/dialyzer/src/dialyzer_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_callgraph.erl
@@ -478,14 +478,37 @@ scan_one_core_fun(TopTree, FunName) ->
call ->
CalleeM = cerl:call_module(Tree),
CalleeF = cerl:call_name(Tree),
- A = length(cerl:call_args(Tree)),
+ CalleeArgs = cerl:call_args(Tree),
+ A = length(CalleeArgs),
case (cerl:is_c_atom(CalleeM) andalso
cerl:is_c_atom(CalleeF)) of
true ->
M = cerl:atom_val(CalleeM),
F = cerl:atom_val(CalleeF),
case erl_bif_types:is_known(M, F, A) of
- true -> Acc;
+ true ->
+ case {M, F, A} of
+ {erlang, make_fun, 3} ->
+ [CA1, CA2, CA3] = CalleeArgs,
+ case
+ cerl:is_c_atom(CA1) andalso
+ cerl:is_c_atom(CA2) andalso
+ cerl:is_c_int(CA3)
+ of
+ true ->
+ MM = cerl:atom_val(CA1),
+ FF = cerl:atom_val(CA2),
+ AA = cerl:int_val(CA3),
+ case erl_bif_types:is_known(MM, FF, AA) of
+ true -> Acc;
+ false -> [{FunName, {MM, FF, AA}}|Acc]
+ end;
+ false ->
+ Acc
+ end;
+ _ ->
+ Acc
+ end;
false -> [{FunName, {M, F, A}}|Acc]
end;
false ->
diff --git a/lib/dialyzer/test/small_SUITE_data/results/fun_arity b/lib/dialyzer/test/small_SUITE_data/results/fun_arity
index 280f5490d0..cc9db65152 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/fun_arity
+++ b/lib/dialyzer/test/small_SUITE_data/results/fun_arity
@@ -31,5 +31,7 @@ fun_arity.erl:81: Function mfa_ne_1_ko/0 has no local return
fun_arity.erl:83: Function mf_ne/1 will never be called
fun_arity.erl:89: Fun application will fail since _cor0 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:89: Function mfa_nd_0_ko/0 has no local return
+fun_arity.erl:90: Call to missing or unexported function fun_arity:mf_nd/0
fun_arity.erl:93: Fun application will fail since _cor0 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:93: Function mfa_nd_1_ko/0 has no local return
+fun_arity.erl:94: Call to missing or unexported function fun_arity:mf_nd/1
diff --git a/lib/dialyzer/test/small_SUITE_data/results/non_existing b/lib/dialyzer/test/small_SUITE_data/results/non_existing
index 58da2bfc8b..b0da5998c7 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/non_existing
+++ b/lib/dialyzer/test/small_SUITE_data/results/non_existing
@@ -1,2 +1,3 @@
+non_existing.erl:12: Call to missing or unexported function lists:non_existing_fun/1
non_existing.erl:9: Call to missing or unexported function lists:non_existing_call/1