diff options
Diffstat (limited to 'lib/dialyzer/src')
-rw-r--r-- | lib/dialyzer/src/dialyzer.erl | 7 | ||||
-rw-r--r-- | lib/dialyzer/src/dialyzer_analysis_callgraph.erl | 13 | ||||
-rw-r--r-- | lib/dialyzer/src/dialyzer_cl.erl | 2 | ||||
-rw-r--r-- | lib/dialyzer/src/dialyzer_contracts.erl | 5 | ||||
-rw-r--r-- | lib/dialyzer/src/dialyzer_gui.erl | 5 | ||||
-rw-r--r-- | lib/dialyzer/src/dialyzer_gui_wx.erl | 5 | ||||
-rw-r--r-- | lib/dialyzer/src/dialyzer_typesig.erl | 57 |
7 files changed, 58 insertions, 36 deletions
diff --git a/lib/dialyzer/src/dialyzer.erl b/lib/dialyzer/src/dialyzer.erl index 63c51e219a..be4b9b6e12 100644 --- a/lib/dialyzer/src/dialyzer.erl +++ b/lib/dialyzer/src/dialyzer.erl @@ -409,9 +409,10 @@ message_to_string({extra_range, [M, F, A, ExtraRanges, SigRange]}) -> io_lib:format("The specification for ~w:~w/~w states that the function" " might also return ~s but the inferred return is ~s\n", [M, F, A, ExtraRanges, SigRange]); -message_to_string({overlapping_contract, []}) -> - "Overloaded contract has overlapping domains;" - " such contracts are currently unsupported and are simply ignored\n"; +message_to_string({overlapping_contract, [M, F, A]}) -> + io_lib:format("Overloaded contract for ~w:~w/~w has overlapping domains;" + " such contracts are currently unsupported and are simply ignored\n", + [M, F, A]); message_to_string({spec_missing_fun, [M, F, A]}) -> io_lib:format("Contract for function that does not exist: ~w:~w/~w\n", [M, F, A]); diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl index 86618a4915..affb89385e 100644 --- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl +++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl @@ -255,14 +255,17 @@ compile_and_store(Files, #analysis_state{codeserver = CServer, CServer2 = dialyzer_codeserver:set_next_core_label(NextLabel, CServer), case Failed =:= [] of true -> - NewFiles = lists:zip(lists:reverse(Modules), Files), ModDict = - lists:foldl(fun({Mod, F}, Dict) -> dict:append(Mod, F, Dict) end, - dict:new(), NewFiles), + lists:foldl(fun(F, Dict) -> + ModFile = lists:last(filename:split(F)), + Mod = filename:basename(ModFile, ".beam"), + dict:append(Mod, F, Dict) + end, + dict:new(), Files), check_for_duplicate_modules(ModDict); false -> - Msg = io_lib:format("Could not scan the following file(s): ~p", - [lists:flatten(Failed)]), + Msg = io_lib:format("Could not scan the following file(s):~n~s", + [[Reason || {_Filename, Reason} <- Failed]]), exit({error, Msg}) end, {T2, _} = statistics(runtime), diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl index 2456585bd0..365c0b36d4 100644 --- a/lib/dialyzer/src/dialyzer_cl.erl +++ b/lib/dialyzer/src/dialyzer_cl.erl @@ -509,7 +509,7 @@ hipe_compile(Files, #options{erlang_mode = ErlangMode} = Options) -> dialyzer_codeserver, dialyzer_contracts, dialyzer_coordinator, dialyzer_dataflow, dialyzer_dep, dialyzer_plt, dialyzer_succ_typings, dialyzer_typesig, - dialyzer_typesig, dialyzer_worker], + dialyzer_worker], report_native_comp(Options), {T1, _} = statistics(wall_clock), native_compile(Mods), diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl index 157c951f77..410be8586e 100644 --- a/lib/dialyzer/src/dialyzer_contracts.erl +++ b/lib/dialyzer/src/dialyzer_contracts.erl @@ -520,6 +520,8 @@ get_invalid_contract_warnings_funs([{MFA, {FileLine, Contract}}|Left], case check_contract(Contract, Sig) of {error, invalid_contract} -> [invalid_contract_warning(MFA, FileLine, Sig, RecDict)|Acc]; + {error, {overlapping_contract, []}} -> + [overlapping_contract_warning(MFA, FileLine)|Acc]; {error, {extra_range, ExtraRanges, STRange}} -> Warn = case t_from_forms_without_remote(Contract#contract.forms, @@ -571,6 +573,9 @@ invalid_contract_warning({M, F, A}, FileLine, SuccType, RecDict) -> SuccTypeStr = dialyzer_utils:format_sig(SuccType, RecDict), {?WARN_CONTRACT_TYPES, FileLine, {invalid_contract, [M, F, A, SuccTypeStr]}}. +overlapping_contract_warning({M, F, A}, FileLine) -> + {?WARN_CONTRACT_TYPES, FileLine, {overlapping_contract, [M, F, A]}}. + extra_range_warning({M, F, A}, FileLine, ExtraRanges, STRange) -> ERangesStr = erl_types:t_to_string(ExtraRanges), STRangeStr = erl_types:t_to_string(STRange), diff --git a/lib/dialyzer/src/dialyzer_gui.erl b/lib/dialyzer/src/dialyzer_gui.erl index ac9844c22c..97e5752577 100644 --- a/lib/dialyzer/src/dialyzer_gui.erl +++ b/lib/dialyzer/src/dialyzer_gui.erl @@ -2,7 +2,7 @@ %%------------------------------------------------------------------------ %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2012. All Rights Reserved. +%% Copyright Ericsson AB 2006-2013. 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 @@ -1331,7 +1331,8 @@ build_analysis_record(#gui_state{mode = Mode, menu = Menu, options = Options, #analysis{defines = Options#options.defines, include_dirs = Options#options.include_dirs, plt = InitPlt, - start_from = StartFrom}. + start_from = StartFrom, + solvers = Options#options.solvers}. get_anal_files(#gui_state{chosen_box = ChosenBox}, StartFrom) -> Files = gs:read(ChosenBox, items), diff --git a/lib/dialyzer/src/dialyzer_gui_wx.erl b/lib/dialyzer/src/dialyzer_gui_wx.erl index c6f7c56227..08f31c1e13 100644 --- a/lib/dialyzer/src/dialyzer_gui_wx.erl +++ b/lib/dialyzer/src/dialyzer_gui_wx.erl @@ -2,7 +2,7 @@ %%------------------------------------------------------------------------ %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2012. All Rights Reserved. +%% Copyright Ericsson AB 2009-2013. 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 @@ -810,7 +810,8 @@ build_analysis_record(#gui_state{mode = Mode, menu = Menu, options = Options, #analysis{defines = Options#options.defines, include_dirs = Options#options.include_dirs, plt = InitPlt, - start_from = StartFrom}. + start_from = StartFrom, + solvers = Options#options.solvers}. get_anal_files(#gui_state{files_to_analyze = Files}, StartFrom) -> FilteredMods = diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl index 17a292a7d6..a418a11e65 100644 --- a/lib/dialyzer/src/dialyzer_typesig.erl +++ b/lib/dialyzer/src/dialyzer_typesig.erl @@ -246,18 +246,27 @@ traverse(Tree, DefinedVars, State) -> Val = cerl:bitstr_val(Tree), {State1, [SizeType, ValType]} = traverse_list([Size, Val], DefinedVars, State), - {State2, TypeConstr} = + {State2, TypeConstr, BinValTypeConstr} = case cerl:bitstr_bitsize(Tree) of - all -> {State1, t_bitstr(UnitVal, 0)}; - utf -> {State1, t_binary()}; % contains an integer number of bytes - N when is_integer(N) -> {State1, t_bitstr(0, N)}; + all -> + T = t_bitstr(UnitVal, 0), + {State1, T, T}; + utf -> + %% contains an integer number of bytes + T = t_binary(), + {State1, T, T}; + N when is_integer(N) -> + {State1, t_bitstr(0, N), t_bitstr(1, N)}; any -> % Size is not a literal + T1 = ?mk_fun_var(bitstr_constr(SizeType, UnitVal), [SizeType]), + T2 = + ?mk_fun_var(bitstr_constr(SizeType, UnitVal, match), [SizeType]), {state__store_conj(SizeType, sub, t_non_neg_integer(), State1), - ?mk_fun_var(bitstr_constr(SizeType, UnitVal), [SizeType])} + T1, T2} end, ValTypeConstr = case cerl:concrete(cerl:bitstr_type(Tree)) of - binary -> TypeConstr; + binary -> BinValTypeConstr; float -> case state__is_in_match(State1) of true -> t_float(); @@ -947,12 +956,20 @@ get_type_test({erlang, is_tuple, 1}) -> {ok, t_tuple()}; get_type_test({M, F, A}) when is_atom(M), is_atom(F), is_integer(A) -> error. bitstr_constr(SizeType, UnitVal) -> + bitstr_constr(SizeType, UnitVal, construct). + +bitstr_constr(SizeType, UnitVal, ConstructOrMatch) -> + Unit = + case ConstructOrMatch of + construct -> 0; + match -> 1 + end, fun(Map) -> TmpSizeType = lookup_type(SizeType, Map), case t_is_subtype(TmpSizeType, t_non_neg_integer()) of true -> case t_number_vals(TmpSizeType) of - [OneSize] -> t_bitstr(0, OneSize * UnitVal); + [OneSize] -> t_bitstr(Unit, OneSize * UnitVal); _ -> MinSize = erl_types:number_min(TmpSizeType), t_bitstr(UnitVal, MinSize * UnitVal) @@ -1770,8 +1787,9 @@ minimize_state(#state{ opaques = Opaques, solvers = Solvers }) -> - ETSCMap = ets:new(cmap,[{read_concurrency, true}]), - ETSPropTypes = ets:new(prop_types,[{read_concurrency, true}]), + Opts = [{read_concurrency, true}], + ETSCMap = ets:new(cmap, Opts), + ETSPropTypes = ets:new(prop_types, Opts), true = ets:insert(ETSCMap, dict:to_list(CMap)), true = ets:insert(ETSPropTypes, dict:to_list(PropTypes)), #state @@ -2111,11 +2129,11 @@ restore_local_map(#v2_state{constr_data = ConData}, Id, Map0) -> {ok, failed} -> Map0; {ok, {[],_}} -> Map0; {ok, {Part0,U}} -> - Part = [{K,V} || {K,V} <- Part0, not lists:member(K, U)], + Part = [KV || {K,_V} = KV <- Part0, not lists:member(K, U)], ?debug("restore local map Id=~w U=~w\n", [Id, U]), pp_map("Part", dict:from_list(Part)), pp_map("Map0", Map0), - Map = lists:foldl(fun({K,V}, D) -> dict:store(K, V, D)end, Map0, Part), + Map = lists:foldl(fun({K,V}, D) -> dict:store(K, V, D) end, Map0, Part), pp_map("Map", Map), Map end. @@ -3374,16 +3392,6 @@ pp_constraints([#constraint{}=C], Level, MaxDepth, _State) -> pp_constraints([#constraint{}=C|Tail], Level, MaxDepth, State) -> pp_op(C, Level), pp_constraints(Tail, Level, MaxDepth, State); -pp_constraints([#constraint_list{type = Type, list = List, id = Id}], - Level, MaxDepth, State) -> - pp_indent(Level), - case Type of - conj -> io:format("Conj ~w (", [Id]); - disj -> io:format("Disj ~w (", [Id]) - end, - NewMaxDepth = pp_constraints(List, Level + 1, MaxDepth, State), - io:format(")", []), - NewMaxDepth; pp_constraints([#constraint_list{type = Type, list = List, id = Id}|Tail], Level, MaxDepth, State) -> pp_indent(Level), @@ -3392,8 +3400,11 @@ pp_constraints([#constraint_list{type = Type, list = List, id = Id}|Tail], disj -> io:format("Disj ~w (", [Id]) end, NewMaxDepth = pp_constraints(List, Level+1, MaxDepth, State), - io:format(")", []), - pp_constraints(Tail, Level, NewMaxDepth, State). + io:format(")"), + case Tail =:= [] of + true -> NewMaxDepth + 1; + false -> pp_constraints(Tail, Level, NewMaxDepth, State) + end. pp_op(#constraint{lhs = Lhs, op = Op, rhs = Rhs}, Level) -> pp_indent(Level), |