From 56b3298377c7422345076f342c0d99901aee34fc Mon Sep 17 00:00:00 2001 From: Hans Bolinder Date: Thu, 20 Oct 2016 14:19:18 +0200 Subject: dialyzer: Fix error handling of bad -dialyzer() attributes If a dialyzer module attribute references an undefined (local) function an error tuple is thrown but no caught. This leads to a 'nocatch' error and not the intended "clean" error. --- lib/dialyzer/src/dialyzer_analysis_callgraph.erl | 40 +++++++++++++----------- lib/dialyzer/src/dialyzer_utils.erl | 21 ++++++++----- 2 files changed, 35 insertions(+), 26 deletions(-) (limited to 'lib/dialyzer/src') diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl index 50fc1d8471..08e55a78bd 100644 --- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl +++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl @@ -406,24 +406,28 @@ compile_common(File, AbstrCode, CompOpts, Callgraph, CServer, {ok, RecInfo} -> CServer1 = dialyzer_codeserver:store_temp_records(Mod, RecInfo, CServer), - MetaFunInfo = - dialyzer_utils:get_fun_meta_info(Mod, AbstrCode, LegalWarnings), - CServer2 = - dialyzer_codeserver:insert_fun_meta_info(MetaFunInfo, CServer1), - case UseContracts of - true -> - case dialyzer_utils:get_spec_info(Mod, AbstrCode, RecInfo) of - {error, _} = Error -> Error; - {ok, SpecInfo, CallbackInfo} -> - CServer3 = - dialyzer_codeserver:store_temp_contracts(Mod, SpecInfo, - CallbackInfo, - CServer2), - store_core(Mod, Core, Callgraph, CServer3) - end; - false -> - store_core(Mod, Core, Callgraph, CServer2) - end + case + dialyzer_utils:get_fun_meta_info(Mod, AbstrCode, LegalWarnings) + of + {error, _} = Error -> Error; + MetaFunInfo -> + CServer2 = + dialyzer_codeserver:insert_fun_meta_info(MetaFunInfo, CServer1), + case UseContracts of + true -> + case dialyzer_utils:get_spec_info(Mod, AbstrCode, RecInfo) of + {error, _} = Error -> Error; + {ok, SpecInfo, CallbackInfo} -> + CServer3 = + dialyzer_codeserver:store_temp_contracts(Mod, SpecInfo, + CallbackInfo, + CServer2), + store_core(Mod, Core, Callgraph, CServer3) + end; + false -> + store_core(Mod, Core, Callgraph, CServer2) + end + end end end. diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl index 76a5cf3d0b..1f2d3e3aaa 100644 --- a/lib/dialyzer/src/dialyzer_utils.erl +++ b/lib/dialyzer/src/dialyzer_utils.erl @@ -514,16 +514,21 @@ get_spec_info([], SpecDict, CallbackDict, {ok, SpecDict, CallbackDict}. -spec get_fun_meta_info(module(), abstract_code(), [dial_warn_tag()]) -> - dialyzer_codeserver:fun_meta_info(). + dialyzer_codeserver:fun_meta_info() | {'error', string()}. get_fun_meta_info(M, Abs, LegalWarnings) -> - NoWarn = get_nowarn_unused_function(M, Abs), - FuncSupp = get_func_suppressions(M, Abs), - Warnings0 = get_options(Abs, LegalWarnings), - Warnings = ordsets:to_list(Warnings0), - ModuleWarnings = [{M, W} || W <- Warnings], - RawProps = lists:append([NoWarn, FuncSupp, ModuleWarnings]), - process_options(dialyzer_utils:family(RawProps), Warnings0). + try + {get_nowarn_unused_function(M, Abs), get_func_suppressions(M, Abs)} + of + {NoWarn, FuncSupp} -> + Warnings0 = get_options(Abs, LegalWarnings), + Warnings = ordsets:to_list(Warnings0), + ModuleWarnings = [{M, W} || W <- Warnings], + RawProps = lists:append([NoWarn, FuncSupp, ModuleWarnings]), + process_options(dialyzer_utils:family(RawProps), Warnings0) + catch throw:{error, _} = Error -> + Error + end. process_options([{M, _}=Mod|Left], Warnings) when is_atom(M) -> [Mod|process_options(Left, Warnings)]; -- cgit v1.2.3