diff options
author | Kostis Sagonas <[email protected]> | 2016-05-08 11:00:46 +0200 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2016-05-13 08:42:46 +0200 |
commit | 756a420b160cbe1ee0507d600dba5c03c0d5e164 (patch) | |
tree | fb6bf4e9ee6ca1a90bedad65f15b15987aacd046 | |
parent | 92fa4c59b303f4bf934915f40601e253393c14c2 (diff) | |
download | otp-756a420b160cbe1ee0507d600dba5c03c0d5e164.tar.gz otp-756a420b160cbe1ee0507d600dba5c03c0d5e164.tar.bz2 otp-756a420b160cbe1ee0507d600dba5c03c0d5e164.zip |
Fix dependency calculation when encountering an erroneous 'apply'
Dialyzer's dependency calculation was throwing an error when
encountering an 'apply' node with something that was not a variable
(e.g., a literal). The rest of the code did not know what to do with
this error, which resulted in dialyzer crashing. Fix this by ingoring
the detected error in the dependency calculation phase; later dialyzer
passes know how to properly handle and report this kind of errors
anyway.
This fixes [Erlang-JIRA] (ERL-138).
-rw-r--r-- | lib/dialyzer/src/dialyzer_dep.erl | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/lib/dialyzer/src/dialyzer_dep.erl b/lib/dialyzer/src/dialyzer_dep.erl index 6678037bc0..490c431488 100644 --- a/lib/dialyzer/src/dialyzer_dep.erl +++ b/lib/dialyzer/src/dialyzer_dep.erl @@ -79,22 +79,26 @@ traverse(Tree, Out, State, CurrentFun) -> apply -> Op = cerl:apply_op(Tree), Args = cerl:apply_args(Tree), - %% Op is always a variable and should not be marked as escaping - %% based on its use. case var =:= cerl:type(Op) of - false -> erlang:error({apply_op_not_a_variable, cerl:type(Op)}); - true -> ok - end, - OpFuns = case map__lookup(cerl_trees:get_label(Op), Out) of - none -> output(none); - {value, OF} -> OF - end, - {ArgFuns, State2} = traverse_list(Args, Out, State, CurrentFun), - State3 = state__add_esc(merge_outs(ArgFuns), State2), - State4 = state__add_deps(CurrentFun, OpFuns, State3), - State5 = state__store_callsite(cerl_trees:get_label(Tree), - OpFuns, length(Args), State4), - {output(set__singleton(external)), State5}; + false -> + %% We have discovered an error here, but we ignore it and let + %% later passes handle it; we do not modify the dependencies. + %% erlang:error({apply_op_not_a_variable, cerl:type(Op)}); + {output(none), State}; + true -> + %% Op is a variable and should not be marked as escaping + %% based on its use. + OpFuns = case map__lookup(cerl_trees:get_label(Op), Out) of + none -> output(none); + {value, OF} -> OF + end, + {ArgFuns, State2} = traverse_list(Args, Out, State, CurrentFun), + State3 = state__add_esc(merge_outs(ArgFuns), State2), + State4 = state__add_deps(CurrentFun, OpFuns, State3), + State5 = state__store_callsite(cerl_trees:get_label(Tree), + OpFuns, length(Args), State4), + {output(set__singleton(external)), State5} + end; binary -> {output(none), State}; 'case' -> |