summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Högberg <john@erlang.org>2023-02-22 12:08:57 +0100
committerGitHub <noreply@github.com>2023-02-22 12:08:57 +0100
commitcfc86388f0536bb660728f1bc4784b90251e9a11 (patch)
tree20e82ebf74e086950594e284cb9fa54df1a6e6ab
parent643d6119a7955d1569acddefb61ef6ce94c15b4f (diff)
parentc2661efb0bdbf54ee288f50fc49be85ff1714fa8 (diff)
downloaderlang-cfc86388f0536bb660728f1bc4784b90251e9a11.tar.gz
Merge pull request #6854 from TD5/add_multiple_plts
dialyzer: Fix crash when adding multiple PLTs OTP-18485 GH-6850 PR-6854
-rw-r--r--lib/dialyzer/src/dialyzer_cl.erl19
-rw-r--r--lib/dialyzer/test/dialyzer_cl_SUITE.erl28
2 files changed, 41 insertions, 6 deletions
diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl
index dd235d9025..a46336617c 100644
--- a/lib/dialyzer/src/dialyzer_cl.erl
+++ b/lib/dialyzer/src/dialyzer_cl.erl
@@ -105,7 +105,16 @@ init_opts_for_build(Opts) ->
add_to_plt(Opts) ->
Opts1 = init_opts_for_add(Opts),
AddFiles = get_files_from_opts(Opts1),
- plt_common(Opts1, [], AddFiles).
+ case Opts1#options.init_plts of
+ [] -> plt_common(Opts1, [], AddFiles);
+ [_] -> plt_common(Opts1, [], AddFiles);
+ PltFiles ->
+ Plts = [dialyzer_cplt:from_file(F) || F <- PltFiles],
+ % Check merge safety
+ _ = dialyzer_cplt:merge_plts_or_report_conflicts(PltFiles, Plts),
+ _ = [plt_common(Opts#options{init_plts=[Plt]}, [], AddFiles) || Plt <- PltFiles],
+ {{?RET_NOTHING_SUSPICIOUS, []}, [], []}
+ end.
init_opts_for_add(Opts) ->
case Opts#options.output_plt =:= none of
@@ -229,19 +238,19 @@ plt_common(#options{init_plts = [InitPlt]} = Opts, RemoveFiles, AddFiles) ->
enrich_with_modules_changed(do_analysis(AnalFiles, Opts, Plt, #plt_info{files=Md5, mod_deps=ModDeps1}), ChangedOrRemovedMods)
end;
{error, no_such_file} ->
- Msg = io_lib:format("Could not find the PLT: ~ts\n~s",
+ Msg = io_lib:format("Could not find the PLT: ~ts~n~s",
[InitPlt, default_plt_error_msg()]),
cl_error(Msg);
{error, not_valid} ->
- Msg = io_lib:format("The file: ~ts is not a valid PLT file\n~s",
+ Msg = io_lib:format("The file: ~ts is not a valid PLT file~n~s",
[InitPlt, default_plt_error_msg()]),
cl_error(Msg);
{error, read_error} ->
- Msg = io_lib:format("Could not read the PLT: ~ts\n~s",
+ Msg = io_lib:format("Could not read the PLT: ~ts~n~s",
[InitPlt, default_plt_error_msg()]),
cl_error(Msg);
{error, {no_file_to_remove, F}} ->
- Msg = io_lib:format("Could not remove the file ~ts from the PLT: ~ts\n",
+ Msg = io_lib:format("Could not remove the file ~ts from the PLT: ~ts~n",
[F, InitPlt]),
cl_error(Msg)
end.
diff --git a/lib/dialyzer/test/dialyzer_cl_SUITE.erl b/lib/dialyzer/test/dialyzer_cl_SUITE.erl
index 49361c959d..b9d176197a 100644
--- a/lib/dialyzer/test/dialyzer_cl_SUITE.erl
+++ b/lib/dialyzer/test/dialyzer_cl_SUITE.erl
@@ -9,14 +9,16 @@
%% Test cases must be exported.
-export([
+ can_add_multiple_plts_to_another_plt/1,
unknown_function_warning_includes_callsite/1,
call_to_missing_warning_includes_callsite/1
]).
-suite() -> [{timetrap, {minutes, 1}}].
+suite() -> [{timetrap, {minutes, 3}}].
all() ->
[
+ can_add_multiple_plts_to_another_plt,
unknown_function_warning_includes_callsite,
call_to_missing_warning_includes_callsite
].
@@ -120,6 +122,30 @@ unknown_function_warning_includes_callsite(Config) when is_list(Config) ->
ok.
+% See GitHub issue erlang/OTP #6850
+can_add_multiple_plts_to_another_plt(Config) when is_list(Config) ->
+
+ PrivDir = proplists:get_value(priv_dir,Config),
+
+ StdlibPlt = filename:join(PrivDir, "stdlib.plt"),
+ ErtsPlt = filename:join(PrivDir, "erts.plt"),
+ OutputPlt = filename:join(PrivDir, "merged.plt"),
+
+ _ = dialyzer:run([{analysis_type, plt_build},
+ {apps, [stdlib]},
+ {output_plt, StdlibPlt}]),
+ _ = dialyzer:run([{analysis_type, plt_build},
+ {apps, [erts]},
+ {output_plt, ErtsPlt}]),
+ ?assertEqual(
+ [],
+ dialyzer:run([{analysis_type, plt_add},
+ {apps, [erts, stdlib]},
+ {plts, [ErtsPlt, StdlibPlt]},
+ {output_plt, OutputPlt}])),
+
+ ok.
+
compile(Config, Module, CompileOpts) ->
Source = lists:concat([Module, ".erl"]),
PrivDir = proplists:get_value(priv_dir,Config),