Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dialyzer: Eliminate the race_conditions option #5502

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions lib/dialyzer/doc/src/dialyzer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -372,13 +372,6 @@ dialyzer --plts plt_1 ... plt_n -- files_to_analyze</code>
<item>
<p>Suppress warnings for unused functions.</p>
</item>
<tag><c>-Wrace_conditions</c> (***)</tag>
<item>
<p>Include warnings for possible race conditions. Notice that the
analysis that finds data races performs intra-procedural data flow
analysis and can sometimes explode in time. Enable it at your own
risk.</p>
</item>
<tag><c>-Wunderspecs</c> (***)</tag>
<item>
<p>Warn about underspecified functions (the specification is strictly
Expand Down
2 changes: 0 additions & 2 deletions lib/dialyzer/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ MODULES = \
dialyzer_gui_wx \
dialyzer_options \
dialyzer_plt \
dialyzer_race_data_server \
dialyzer_races \
dialyzer_succ_typings \
dialyzer_timing \
dialyzer_typesig \
Expand Down
2 changes: 0 additions & 2 deletions lib/dialyzer/src/dialyzer.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@
dialyzer_gui_wx,
dialyzer_options,
dialyzer_plt,
dialyzer_race_data_server,
dialyzer_races,
dialyzer_succ_typings,
dialyzer_typesig,
dialyzer_utils,
Expand Down
4 changes: 0 additions & 4 deletions lib/dialyzer/src/dialyzer.erl
Original file line number Diff line number Diff line change
Expand Up @@ -503,10 +503,6 @@ message_to_string({opaque_size, [SizeType, Size]}, I, _E) ->
message_to_string({opaque_call, [M, F, Args, Culprit, OpaqueType]}, I, _E) ->
io_lib:format("The call ~s:~ts~ts breaks the opacity of the term ~ts :: ~ts\n",
[M, F, a(Args, I), c(Culprit, I), t(OpaqueType, I)]);
%%----- Warnings for concurrency errors --------------------
message_to_string({race_condition, [M, F, Args, Reason]}, I, _E) ->
%% There is a possibly huge type in Reason.
io_lib:format("The call ~w:~tw~ts ~ts\n", [M, F, a(Args, I), Reason]);
%%----- Warnings for behaviour errors --------------------
message_to_string({callback_type_mismatch, [B, F, A, ST, CT]}, I, _E) ->
io_lib:format("The inferred return type of ~tw/~w ~ts has nothing in"
Expand Down
5 changes: 1 addition & 4 deletions lib/dialyzer/src/dialyzer.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
-define(WARN_CONTRACT_RANGE, warn_contract_range).
-define(WARN_CALLGRAPH, warn_callgraph).
-define(WARN_UNMATCHED_RETURN, warn_umatched_return).
-define(WARN_RACE_CONDITION, warn_race_condition).
-define(WARN_BEHAVIOUR, warn_behaviour).
-define(WARN_UNDEFINED_CALLBACK, warn_undefined_callbacks).
-define(WARN_UNKNOWN, warn_unknown).
Expand All @@ -71,7 +70,7 @@
| ?WARN_FUN_APP | ?WARN_MAP_CONSTRUCTION
| ?WARN_MATCHING | ?WARN_NON_PROPER_LIST
| ?WARN_NOT_CALLED | ?WARN_OPAQUE
| ?WARN_RACE_CONDITION | ?WARN_RETURN_NO_RETURN
| ?WARN_RETURN_NO_RETURN
| ?WARN_RETURN_ONLY_EXIT | ?WARN_UNDEFINED_CALLBACK
| ?WARN_UNKNOWN | ?WARN_UNMATCHED_RETURN.

Expand Down Expand Up @@ -126,7 +125,6 @@
| 'no_undefined_callbacks'
| 'no_underspecs'
| 'no_unused'
| 'race_conditions'
| 'underspecs'
| 'unknown'
| 'unmatched_returns'
Expand Down Expand Up @@ -180,7 +178,6 @@
start_from = byte_code :: start_from(),
plt :: dialyzer_plt:plt(),
use_contracts = true :: boolean(),
race_detection = false :: boolean(),
behaviours_chk = false :: boolean(),
timing = false :: boolean() | 'debug',
timing_server = none :: dialyzer_timing:timing_server(),
Expand Down
11 changes: 2 additions & 9 deletions lib/dialyzer/src/dialyzer_analysis_callgraph.erl
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,8 @@

start(Parent, LegalWarnings, Analysis) ->
TimingServer = dialyzer_timing:init(Analysis#analysis.timing),
RacesOn = ordsets:is_element(?WARN_RACE_CONDITION, LegalWarnings),
Analysis0 =
Analysis#analysis{race_detection = RacesOn, timing_server = TimingServer},
Analysis#analysis{timing_server = TimingServer},
Analysis1 = expand_files(Analysis0),
Analysis2 = run_analysis(Analysis1, LegalWarnings),
State = #server_state{parent = Parent},
Expand Down Expand Up @@ -145,17 +144,11 @@ analysis_start(Parent, Analysis, LegalWarnings) ->
Exports = dialyzer_codeserver:get_exports(NewCServer),
NonExports = sets:subtract(sets:from_list(AllNodes, [{version, 2}]), Exports),
NonExportsList = sets:to_list(NonExports),
NewCallgraph =
case Analysis#analysis.race_detection of
true -> dialyzer_callgraph:put_race_detection(true, Callgraph);
false -> Callgraph
end,
State2 = analyze_callgraph(NewCallgraph, State1),
State2 = analyze_callgraph(Callgraph, State1),
#analysis_state{plt = Plt2,
doc_plt = DocPlt,
codeserver = Codeserver0} = State2,
{Codeserver, Plt3} = move_data(Codeserver0, Plt2),
dialyzer_callgraph:dispose_race_server(NewCallgraph),
%% Since the PLT is never used, a dummy is sent:
DummyPlt = dialyzer_plt:new(),
send_codeserver_plt(Parent, Codeserver, DummyPlt),
Expand Down
158 changes: 6 additions & 152 deletions lib/dialyzer/src/dialyzer_callgraph.erl
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,13 @@
get_depends_on/2,
%% get_required_by/2,
in_neighbours/2,
renew_race_info/4,
renew_race_code/2,
renew_race_public_tables/2,
reset_from_funs/2,
scan_core_tree/2,
strip_module_deps/2,
remove_external/1,
to_dot/2,
to_ps/3]).

-export([cleanup/1, get_digraph/1, get_named_tables/1, get_public_tables/1,
get_race_code/1, get_race_detection/1, race_code_new/1,
put_digraph/2, put_race_code/2, put_race_detection/2,
put_named_tables/2, put_public_tables/2, put_behaviour_api_calls/2,
get_behaviour_api_calls/1, dispose_race_server/1, duplicate/1]).

-export_type([callgraph/0, mfa_or_funlbl/0, callgraph_edge/0, mod_deps/0]).

-include("dialyzer.hrl").
Expand Down Expand Up @@ -89,24 +80,15 @@
%% whenever applicable.
%%-----------------------------------------------------------------------------

%% Types with comment 'race' are due to dialyzer_races.erl.
-record(callgraph, {digraph = digraph:new() :: digraph:graph(),
active_digraph :: active_digraph()
| 'undefined', % race
esc :: ets:tid()
| 'undefined', % race
letrec_map :: ets:tid()
| 'undefined', % race
active_digraph :: active_digraph() | 'undefined',
esc :: ets:tid(),
letrec_map :: ets:tid(),
name_map :: ets:tid(),
rev_name_map :: ets:tid(),
rec_var_map :: ets:tid()
| 'undefined', % race
self_rec :: ets:tid()
| 'undefined', % race
calls :: ets:tid()
| 'undefined', % race
race_detection = false :: boolean(),
race_data_server = dialyzer_race_data_server:new() :: pid()}).
rec_var_map :: ets:tid(),
self_rec :: ets:tid(),
calls :: ets:tid()}).

%% Exported Types

Expand Down Expand Up @@ -620,134 +602,6 @@ digraph_reaching_subgraph(Funs, DG) ->
Vertices = digraph_utils:reaching(Funs, DG),
digraph_utils:subgraph(DG, Vertices).

%%----------------------------------------------------------------------
%% Races
%%----------------------------------------------------------------------

-spec renew_race_info(callgraph(), dict:dict(), [label()], [string()]) ->
callgraph().

renew_race_info(#callgraph{race_data_server = RaceDataServer} = CG,
RaceCode, PublicTables, NamedTables) ->
ok = dialyzer_race_data_server:cast(
{renew_race_info, {RaceCode, PublicTables, NamedTables}},
RaceDataServer),
CG.

-spec renew_race_code(dialyzer_races:races(), callgraph()) -> callgraph().

renew_race_code(Races, #callgraph{race_data_server = RaceDataServer} = CG) ->
Fun = dialyzer_races:get_curr_fun(Races),
FunArgs = dialyzer_races:get_curr_fun_args(Races),
Code = lists:reverse(dialyzer_races:get_race_list(Races)),
ok = dialyzer_race_data_server:cast(
{renew_race_code, {Fun, FunArgs, Code}},
RaceDataServer),
CG.

-spec renew_race_public_tables(label(), callgraph()) -> callgraph().

renew_race_public_tables(VarLabel,
#callgraph{race_data_server = RaceDataServer} = CG) ->
ok =
dialyzer_race_data_server:cast({renew_race_public_tables, VarLabel}, RaceDataServer),
CG.

-spec cleanup(callgraph()) -> callgraph().

cleanup(#callgraph{digraph = Digraph,
name_map = NameMap,
rev_name_map = RevNameMap,
race_data_server = RaceDataServer}) ->
#callgraph{digraph = Digraph,
name_map = NameMap,
rev_name_map = RevNameMap,
race_data_server = dialyzer_race_data_server:duplicate(RaceDataServer)}.

-spec duplicate(callgraph()) -> callgraph().

duplicate(#callgraph{race_data_server = RaceDataServer} = Callgraph) ->
Callgraph#callgraph{
race_data_server = dialyzer_race_data_server:duplicate(RaceDataServer)}.

-spec dispose_race_server(callgraph()) -> ok.

dispose_race_server(#callgraph{race_data_server = RaceDataServer}) ->
dialyzer_race_data_server:stop(RaceDataServer).

-spec get_digraph(callgraph()) -> digraph:graph().

get_digraph(#callgraph{digraph = Digraph}) ->
Digraph.

-spec get_named_tables(callgraph()) -> [string()].

get_named_tables(#callgraph{race_data_server = RaceDataServer}) ->
dialyzer_race_data_server:call(get_named_tables, RaceDataServer).

-spec get_public_tables(callgraph()) -> [label()].

get_public_tables(#callgraph{race_data_server = RaceDataServer}) ->
dialyzer_race_data_server:call(get_public_tables, RaceDataServer).

-spec get_race_code(callgraph()) -> dict:dict().

get_race_code(#callgraph{race_data_server = RaceDataServer}) ->
dialyzer_race_data_server:call(get_race_code, RaceDataServer).

-spec get_race_detection(callgraph()) -> boolean().

get_race_detection(#callgraph{race_detection = RD}) ->
RD.

-spec get_behaviour_api_calls(callgraph()) -> [{mfa(), mfa()}].

get_behaviour_api_calls(#callgraph{race_data_server = RaceDataServer}) ->
dialyzer_race_data_server:call(get_behaviour_api_calls, RaceDataServer).

-spec race_code_new(callgraph()) -> callgraph().

race_code_new(#callgraph{race_data_server = RaceDataServer} = CG) ->
ok = dialyzer_race_data_server:cast(race_code_new, RaceDataServer),
CG.

-spec put_digraph(digraph:graph(), callgraph()) -> callgraph().

put_digraph(Digraph, Callgraph) ->
Callgraph#callgraph{digraph = Digraph}.

-spec put_race_code(dict:dict(), callgraph()) -> callgraph().

put_race_code(RaceCode, #callgraph{race_data_server = RaceDataServer} = CG) ->
ok = dialyzer_race_data_server:cast({put_race_code, RaceCode}, RaceDataServer),
CG.

-spec put_race_detection(boolean(), callgraph()) -> callgraph().

put_race_detection(RaceDetection, Callgraph) ->
Callgraph#callgraph{race_detection = RaceDetection}.

-spec put_named_tables([string()], callgraph()) -> callgraph().

put_named_tables(NamedTables,
#callgraph{race_data_server = RaceDataServer} = CG) ->
ok = dialyzer_race_data_server:cast({put_named_tables, NamedTables}, RaceDataServer),
CG.

-spec put_public_tables([label()], callgraph()) -> callgraph().

put_public_tables(PublicTables,
#callgraph{race_data_server = RaceDataServer} = CG) ->
ok = dialyzer_race_data_server:cast({put_public_tables, PublicTables}, RaceDataServer),
CG.

-spec put_behaviour_api_calls([{mfa(), mfa()}], callgraph()) -> callgraph().

put_behaviour_api_calls(Calls,
#callgraph{race_data_server = RaceDataServer} = CG) ->
ok = dialyzer_race_data_server:cast({put_behaviour_api_calls, Calls}, RaceDataServer),
CG.

%%=============================================================================
%% Utilities for 'dot'
%%=============================================================================
Expand Down
2 changes: 0 additions & 2 deletions lib/dialyzer/src/dialyzer_cl_parse.erl
Original file line number Diff line number Diff line change
Expand Up @@ -544,8 +544,6 @@ warning_options_msg() ->
value or do not match against one of many possible return value(s).
-Werror_handling ***
Include warnings for functions that only return by means of an exception.
-Wrace_conditions ***
Include warnings for possible race conditions.
-Wunderspecs ***
Warn about underspecified functions
(those whose -spec is strictly more allowing than the success typing).
Expand Down
Loading