diff options
Diffstat (limited to 'lib/dialyzer/src/dialyzer_dep.erl')
-rw-r--r-- | lib/dialyzer/src/dialyzer_dep.erl | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/lib/dialyzer/src/dialyzer_dep.erl b/lib/dialyzer/src/dialyzer_dep.erl index a81ea1a98b..f1ac41ff04 100644 --- a/lib/dialyzer/src/dialyzer_dep.erl +++ b/lib/dialyzer/src/dialyzer_dep.erl @@ -2,7 +2,7 @@ %%----------------------------------------------------------------------- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2010. All Rights Reserved. +%% Copyright Ericsson AB 2006-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -59,13 +59,13 @@ %% -spec analyze(cerl:c_module()) -> - {dict(), ordset('external' | label()), dict(), dict()}. + {dict:dict(), ordset('external' | label()), dict:dict(), dict:dict()}. analyze(Tree) -> %% io:format("Handling ~w\n", [cerl:atom_val(cerl:module_name(Tree))]), {_, State} = traverse(Tree, map__new(), state__new(Tree), top), Esc = state__esc(State), - %% Add dependency from 'external' to all escaping function + %% Add dependency from 'external' to all escaping functions State1 = state__add_deps(external, output(Esc), State), Deps = state__deps(State1), Calls = state__calls(State1), @@ -309,7 +309,7 @@ primop(Tree, ArgFuns, State) -> %% Set %% --record(set, {set :: set()}). +-record(set, {set :: sets:set()}). set__singleton(Val) -> #set{set = sets:add_element(Val, sets:new())}. @@ -478,19 +478,30 @@ all_vars(Tree, AccIn) -> -type local_set() :: 'none' | #set{}. --record(state, {deps :: dict(), +-record(state, {deps :: dict:dict(), esc :: local_set(), - call :: dict(), - arities :: dict(), - letrecs :: dict()}). + call :: dict:dict(), + arities :: dict:dict(), + letrecs :: dict:dict()}). state__new(Tree) -> Exports = set__from_list([X || X <- cerl:module_exports(Tree)]), - InitEsc = set__from_list([cerl_trees:get_label(Fun) - || {Var, Fun} <- cerl:module_defs(Tree), - set__is_element(Var, Exports)]), + %% get the labels of all exported functions + ExpLs = [cerl_trees:get_label(Fun) || {Var, Fun} <- cerl:module_defs(Tree), + set__is_element(Var, Exports)], + %% make sure to also initiate an analysis from all functions called + %% from on_load attributes; in Core these exist as a list of {F,A} pairs + OnLoadFAs = lists:flatten([cerl:atom_val(Args) + || {Attr, Args} <- cerl:module_attrs(Tree), + cerl:atom_val(Attr) =:= on_load]), + OnLoadLs = [cerl_trees:get_label(Fun) + || {Var, Fun} <- cerl:module_defs(Tree), + lists:member(cerl:var_name(Var), OnLoadFAs)], + %% init the escaping function labels to exported + called from on_load + InitEsc = set__from_list(OnLoadLs ++ ExpLs), Arities = cerl_trees:fold(fun find_arities/2, dict:new(), Tree), - #state{deps = map__new(), esc = InitEsc, call = map__new(), arities = Arities, letrecs = map__new()}. + #state{deps = map__new(), esc = InitEsc, call = map__new(), + arities = Arities, letrecs = map__new()}. find_arities(Tree, AccMap) -> case cerl:is_c_fun(Tree) of |