aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/test/race_SUITE_data/src
diff options
context:
space:
mode:
authorStavros Aronis <[email protected]>2011-04-02 18:57:42 +0300
committerHenrik Nord <[email protected]>2011-05-04 15:06:15 +0200
commitca4633fd683527097451ca1398c90c87bb5c14fc (patch)
tree3d8e18c9becd4feb7d3ceb1eed24bdce2ef69dd6 /lib/dialyzer/test/race_SUITE_data/src
parentbc619f0cbf9555df6dfc44a499f0cd9cee8bd1be (diff)
downloadotp-ca4633fd683527097451ca1398c90c87bb5c14fc.tar.gz
otp-ca4633fd683527097451ca1398c90c87bb5c14fc.tar.bz2
otp-ca4633fd683527097451ca1398c90c87bb5c14fc.zip
Rename suite data directories
Diffstat (limited to 'lib/dialyzer/test/race_SUITE_data/src')
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_args1.erl17
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_args2.erl17
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_args3.erl17
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_args4.erl17
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_args5.erl17
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_args6.erl17
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_args7.erl17
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_args8.erl16
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow1.erl20
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow2.erl26
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow3.erl31
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow4.erl31
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow5.erl34
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race1.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race2.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race3.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race4.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race5.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race6.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_double1.erl28
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_double2.erl28
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_funs1.erl18
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_funs2.erl18
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_new.erl15
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/ets_insert_param.erl26
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/extract_translations.erl293
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/mnesia_diff_atoms_race1.erl33
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/mnesia_diff_atoms_race2.erl37
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_one_write_two.erl20
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_two_write_one.erl20
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double1.erl25
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double2.erl25
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double3.erl25
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double4.erl25
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_one.erl20
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_two.erl20
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow1.erl17
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow2.erl19
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow3.erl25
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow4.erl29
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow5.erl12
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow6.erl12
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_atoms_no_race.erl23
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_atoms_race.erl34
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1_nested.erl23
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1_pathsens.erl32
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1_twice.erl30
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2.erl25
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2_nested.erl20
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2_pathsens.erl29
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2_twice.erl27
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions3.erl11
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions3_nested.erl21
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions3_pathsens.erl29
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions4.erl32
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions5.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions6.erl29
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1/whereis_diff_modules1.erl16
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1/whereis_diff_modules2.erl11
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_pathsens/whereis_diff_modules1_pathsens.erl26
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_pathsens/whereis_diff_modules2_pathsens.erl12
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_rec/whereis_diff_modules1_rec.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_rec/whereis_diff_modules2_rec.erl8
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2/whereis_diff_modules3.erl8
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2/whereis_diff_modules4.erl11
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_pathsens/whereis_diff_modules3_pathsens.erl25
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_pathsens/whereis_diff_modules4_pathsens.erl13
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_rec/whereis_diff_modules3_rec.erl25
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_rec/whereis_diff_modules4_rec.erl8
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules3/whereis_diff_modules5.erl23
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules3/whereis_diff_modules6.erl11
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_nested/whereis_diff_modules1_nested.erl14
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_nested/whereis_diff_modules2_nested.erl11
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_nested/whereis_diff_modules3_nested.erl11
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_twice/whereis_diff_modules1_twice.erl21
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_twice/whereis_diff_modules2_twice.erl11
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_vars_no_race.erl13
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_diff_vars_race.erl19
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module1/whereis_intra_inter_module1.erl19
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module1/whereis_intra_inter_module2.erl11
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module2/whereis_intra_inter_module3.erl16
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module2/whereis_intra_inter_module4.erl14
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module3/whereis_intra_inter_module5.erl19
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module3/whereis_intra_inter_module6.erl14
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module4/whereis_intra_inter_module7.erl11
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module4/whereis_intra_inter_module8.erl13
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module5/whereis_intra_inter_module10.erl16
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module5/whereis_intra_inter_module9.erl11
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module6/whereis_intra_inter_module11.erl27
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module6/whereis_intra_inter_module12.erl14
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module7/whereis_intra_inter_module13.erl19
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module7/whereis_intra_inter_module14.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module8/whereis_intra_inter_module15.erl19
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module8/whereis_intra_inter_module16.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_param.erl16
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_param_inter_module/whereis_param_inter_module1.erl8
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_param_inter_module/whereis_param_inter_module2.erl13
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function1.erl19
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function2.erl24
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function3.erl27
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function4.erl27
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function5.erl21
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function6.erl24
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function7.erl19
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function8.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_try_catch.erl25
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars1.erl17
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars10.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars11.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars12.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars13.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars14.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars15.erl23
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars16.erl23
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars17.erl23
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars18.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars19.erl23
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars2.erl18
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars20.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars21.erl23
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars22.erl27
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars3.erl18
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars4.erl18
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars5.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars6.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars7.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars8.erl22
-rw-r--r--lib/dialyzer/test/race_SUITE_data/src/whereis_vars9.erl22
129 files changed, 2916 insertions, 0 deletions
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args1.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args1.erl
new file mode 100644
index 0000000000..0039195e0a
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args1.erl
@@ -0,0 +1,17 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account the argument types of the calls.
+
+-module(ets_insert_args1).
+-export([start/0]).
+
+start() ->
+ F = fun(T) -> [{_, N}] = ets:lookup(T, counter),
+ ets:insert(T, [{counter, N+1}])
+ end,
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {counter, 0}),
+ io:format("Inserted ~w\n", [{counter, 0}]),
+ F(foo),
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, counter),
+ io:format("Counter: ~w\n", [ObjectList]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args2.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args2.erl
new file mode 100644
index 0000000000..c1857eb58b
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args2.erl
@@ -0,0 +1,17 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account the argument types of the calls.
+
+-module(ets_insert_args2).
+-export([start/0]).
+
+start() ->
+ F = fun(T)-> [{_, N}] = ets:lookup(T, counter),
+ ets:insert(T, [{counter, N+1}, {maria, N+1}, {kostis, N+1}])
+ end,
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {counter, 0}),
+ io:format("Inserted ~w\n", [{counter, 0}]),
+ F(foo),
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, counter),
+ io:format("Counter: ~w\n", [ObjectList]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args3.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args3.erl
new file mode 100644
index 0000000000..74401b76fd
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args3.erl
@@ -0,0 +1,17 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account the argument types of the calls.
+
+-module(ets_insert_args3).
+-export([start/0]).
+
+start() ->
+ F = fun(T)-> [{_, N}] = ets:lookup(T, counter),
+ ets:insert(T, [{maria, N+1}, {kostis, N+1}])
+ end,
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {counter, 0}),
+ io:format("Inserted ~w\n", [{counter, 0}]),
+ F(foo),
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, counter),
+ io:format("Counter: ~w\n", [ObjectList]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args4.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args4.erl
new file mode 100644
index 0000000000..2c892074ec
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args4.erl
@@ -0,0 +1,17 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account the argument types of the calls.
+
+-module(ets_insert_args4).
+-export([start/0]).
+
+start() ->
+ F = fun(T)-> [{_, N}] = ets:lookup(T, counter),
+ ets:insert(T, {counter, N+1})
+ end,
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {counter, 0}),
+ io:format("Inserted ~w\n", [{counter, 0}]),
+ F(foo),
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, counter),
+ io:format("Counter: ~w\n", [ObjectList]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args5.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args5.erl
new file mode 100644
index 0000000000..156f555a7c
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args5.erl
@@ -0,0 +1,17 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account the argument types of the calls.
+
+-module(ets_insert_args5).
+-export([start/0]).
+
+start() ->
+ F = fun(T)-> [{_, N}] = ets:lookup(T, counter),
+ ets:insert(T, {counter, N+1, N+2})
+ end,
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {counter, 0, 0}),
+ io:format("Inserted ~w\n", [{counter, 0, 0}]),
+ F(foo),
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, counter),
+ io:format("Counter: ~w\n", [ObjectList]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args6.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args6.erl
new file mode 100644
index 0000000000..1e5887f76d
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args6.erl
@@ -0,0 +1,17 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account the argument types of the calls.
+
+-module(ets_insert_args6).
+-export([start/0]).
+
+start() ->
+ F = fun(T)-> [{_, N}] = ets:lookup(T, counter),
+ ets:insert(T, [{counter, N+1, N+2}])
+ end,
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {counter, 0, 0}),
+ io:format("Inserted ~w\n", [{counter, 0, 0}]),
+ F(foo),
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, counter),
+ io:format("Counter: ~w\n", [ObjectList]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args7.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args7.erl
new file mode 100644
index 0000000000..912bbf7073
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args7.erl
@@ -0,0 +1,17 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account the argument types of the calls.
+
+-module(ets_insert_args7).
+-export([test/0]).
+
+test() ->
+ Foo = foo,
+ ets:new(Foo, [named_table, public]),
+ race(Foo).
+
+race(Tab) ->
+ [{_, N}] = ets:lookup(Tab, counter),
+ aux(Tab, N).
+
+aux(Table, N) ->
+ ets:insert(Table, [{counter, N+1}]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args8.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args8.erl
new file mode 100644
index 0000000000..275cf0291c
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_args8.erl
@@ -0,0 +1,16 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account the argument types of the calls.
+
+-module(ets_insert_args8).
+-export([test/1]).
+
+test(Foo) ->
+ ets:new(Foo, [named_table, public]),
+ race(Foo).
+
+race(Tab) ->
+ [{_, N}] = ets:lookup(Tab, counter),
+ aux(Tab, N).
+
+aux(Table, N) ->
+ ets:insert(Table, [{counter, N+1}]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow1.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow1.erl
new file mode 100644
index 0000000000..cfe0b2b727
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow1.erl
@@ -0,0 +1,20 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account control flow that might exist.
+
+-module(ets_insert_control_flow1).
+-export([start/0]).
+
+start() ->
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {random, random:uniform(maria:get_int())}),
+ io:format("Inserted ~w\n", [{_, N}] = ets:lookup(foo, random)),
+ case (N rem 2 == 0) of
+ true ->
+ io:format("\nInserted an even number\n", []),
+ io:format("\nWill make it odd\n", []),
+ ets:insert(foo, {random, N+1});
+ false -> ok
+ end,
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, random),
+ io:format("Random odd integer: ~w\n", [ObjectList]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow2.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow2.erl
new file mode 100644
index 0000000000..d160418bdb
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow2.erl
@@ -0,0 +1,26 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account control flow that might exist.
+
+-module(ets_insert_control_flow2).
+-export([start/0]).
+
+start() ->
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {random, random:uniform(150)}),
+ io:format("Inserted ~w\n", [{_, N}] = ets:lookup(foo, random)),
+ case (N rem 2 == 0) of
+ true ->
+ io:format("\nInserted an even integer\n", []),
+ io:format("\nWill make it odd and generate password\n", []),
+ ets:insert(foo, [{random, N+1}, {pass, generate_password(N)}]);
+ false ->
+ io:format("\nInserted an odd integer\n", []),
+ io:format("\nWill make it even and generate password\n", []),
+ ets:insert(foo, [{random, N+1}, {pass, generate_password(N)}])
+ end,
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, pass),
+ io:format("New password: ~w\n", [ObjectList]).
+
+generate_password(N) ->
+ lists:map(fun (_) -> random:uniform(90)+$\s+1 end, lists:seq(1,N)).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow3.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow3.erl
new file mode 100644
index 0000000000..9c6a22eb05
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow3.erl
@@ -0,0 +1,31 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account control flow that might exist.
+
+-module(ets_insert_control_flow3).
+-export([start/1]).
+
+start(User) ->
+ Table = ets:new(table, [public]),
+ mod:process(Table),
+ [{_, N}] =
+ case User of
+ root -> ets:lookup(Table, root);
+ user -> ets:lookup(Table, user);
+ Other -> [{undefined, -1}]
+ end,
+ case N of
+ -1 -> io:format("\nUnknown User\n", []);
+ 0 ->
+ case User of
+ root ->
+ ets:insert(Table, {User, Pass = generate_password(N) ++ generate_password(N+1)});
+ user ->
+ ets:insert(Table, {User, Pass = generate_password(N)})
+ end,
+ io:format("\nYour new pass is ~w\n", [Pass]);
+ P ->
+ io:format("\nYour pass is ~w\n", [P])
+ end.
+
+generate_password(N) ->
+ lists:map(fun (_) -> random:uniform(90)+$\s+1 end, lists:seq(1,N)).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow4.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow4.erl
new file mode 100644
index 0000000000..caa3804614
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow4.erl
@@ -0,0 +1,31 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account control flow that might exist.
+
+-module(ets_insert_control_flow4).
+-export([start/1]).
+
+start(User) ->
+ Table = ets:new(table, [public]),
+ mod:process(Table),
+ [{_, N}] =
+ case User of
+ root -> ets:lookup(Table, pass);
+ user -> ets:lookup(Table, pass);
+ _Other -> [{undefined, -1}]
+ end,
+ case N of
+ -1 -> io:format("\nUnknown User\n", []);
+ 0 ->
+ case User of
+ root ->
+ ets:insert(Table, {pass, Pass = generate_password(N) ++ generate_password(N+1)});
+ user ->
+ ets:insert(Table, {pass, Pass = generate_password(N)})
+ end,
+ io:format("\nYour new pass is ~w\n", [Pass]);
+ P ->
+ io:format("\nYour pass is ~w\n", [P])
+ end.
+
+generate_password(N) ->
+ lists:map(fun (_) -> random:uniform(90)+$\s+1 end, lists:seq(1,N)).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow5.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow5.erl
new file mode 100644
index 0000000000..b19fd776ec
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_control_flow5.erl
@@ -0,0 +1,34 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account control flow that might exist.
+
+-module(ets_insert_control_flow5).
+-export([start/1]).
+
+start(User) ->
+ Table = ets:new(table, [public]),
+ mod:process(Table),
+ [{_, N}] =
+ case User of
+ root -> ets:lookup(Table, pass);
+ user -> ets:lookup(Table, pass);
+ Other -> [{undefined, -1}]
+ end,
+ [{_, Msg}] = ets:lookup(Table, welcome_msg),
+ case N of
+ -1 -> io:format("\nUnknown User\n", []);
+ 0 ->
+ case User of
+ root ->
+ ets:insert(Table, {welcome_msg, Msg ++ "root"}),
+ ets:insert(Table, {pass, Pass = generate_password(N) ++ generate_password(N+1)});
+ user ->
+ ets:insert(Table, {welcome_msg, Msg ++ "user"}),
+ ets:insert(Table, {pass, Pass = generate_password(N)})
+ end,
+ io:format("\nYour new pass is ~w\n", [Pass]);
+ P ->
+ io:format("\nYour pass is ~w\n", [P])
+ end.
+
+generate_password(N) ->
+ lists:map(fun (_) -> random:uniform(90)+$\s+1 end, lists:seq(1,N)).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race1.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race1.erl
new file mode 100644
index 0000000000..7b2dbb8eff
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race1.erl
@@ -0,0 +1,22 @@
+%% This tests that the race condition detection between ets:lookup/
+%% ets:insert is robust even when the functions are called with
+%% different atoms as arguments.
+
+-module(ets_insert_diff_atoms_race1).
+-export([test/0]).
+
+test() ->
+ ets:new(foo, [named_table, public]),
+ {race(foo), no_race(foo)}.
+
+race(Tab) ->
+ [{_, N}] = ets:lookup(Tab, counter),
+ aux(Tab, N).
+
+no_race(Tab) ->
+ [{_, N}] = ets:lookup(Tab, counter),
+ AnotherTab = bar,
+ aux(AnotherTab, N).
+
+aux(Table, N) ->
+ ets:insert(Table, [{counter, N+1}]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race2.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race2.erl
new file mode 100644
index 0000000000..d7afc79d07
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race2.erl
@@ -0,0 +1,22 @@
+%% This tests that the race condition detection between ets:lookup/
+%% ets:insert is robust even when the functions are called with
+%% different atoms as arguments.
+
+-module(ets_insert_diff_atoms_race2).
+-export([test/0]).
+
+test() ->
+ ets:new(foo, [named_table, public]),
+ {race(foo, counter), no_race(foo, counter)}.
+
+race(Tab, Counter) ->
+ [{_, N}] = ets:lookup(Tab, Counter),
+ aux(Tab, Counter, N).
+
+no_race(Tab, Counter) ->
+ [{_, N}] = ets:lookup(Tab, Counter),
+ AnotherTab = bar,
+ aux(AnotherTab, Counter, N).
+
+aux(Table, Counter, N) ->
+ ets:insert(Table, [{Counter, N+1}]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race3.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race3.erl
new file mode 100644
index 0000000000..e05e9be54b
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race3.erl
@@ -0,0 +1,22 @@
+%% This tests that the race condition detection between ets:lookup/
+%% ets:insert is robust even when the functions are called with
+%% different atoms as arguments.
+
+-module(ets_insert_diff_atoms_race3).
+-export([test/0]).
+
+test() ->
+ ets:new(foo, [named_table, public]),
+ {race(foo), no_race(foo)}.
+
+race(Tab) ->
+ [{_, N}] = ets:lookup(Tab, counter),
+ aux(Tab, N).
+
+no_race(Tab) ->
+ [{_, N}] = ets:lookup(Tab, counter),
+ AnotherTab = bar,
+ aux(AnotherTab, N).
+
+aux(Table, N) ->
+ ets:insert(Table, {counter, N+1}).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race4.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race4.erl
new file mode 100644
index 0000000000..e2a3588f41
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race4.erl
@@ -0,0 +1,22 @@
+%% This tests that the race condition detection between ets:lookup/
+%% ets:insert is robust even when the functions are called with
+%% different atoms as arguments.
+
+-module(ets_insert_diff_atoms_race4).
+-export([test/0]).
+
+test() ->
+ ets:new(foo, [named_table, public]),
+ {race(foo, counter), no_race(foo, counter)}.
+
+race(Tab, Counter) ->
+ [{_, N}] = ets:lookup(Tab, Counter),
+ aux(Tab, Counter, N).
+
+no_race(Tab, Counter) ->
+ [{_, N}] = ets:lookup(Tab, Counter),
+ AnotherTab = bar,
+ aux(AnotherTab, Counter, N).
+
+aux(Table, Counter, N) ->
+ ets:insert(Table, {Counter, N+1}).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race5.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race5.erl
new file mode 100644
index 0000000000..dd53387c11
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race5.erl
@@ -0,0 +1,22 @@
+%% This tests that the race condition detection between ets:lookup/
+%% ets:insert is robust even when the functions are called with
+%% different atoms as arguments.
+
+-module(ets_insert_diff_atoms_race5).
+-export([test/0]).
+
+test() ->
+ ets:new(foo, [named_table, public]),
+ {race(foo, counter), no_race(foo, counter)}.
+
+race(Tab, Counter) ->
+ [{_, N}] = ets:lookup(Tab, Counter),
+ aux(Tab, Counter, N).
+
+no_race(Tab, Counter) ->
+ [{_, N}] = ets:lookup(Tab, Counter),
+ AnotherCounter = index,
+ aux(Tab, AnotherCounter, N).
+
+aux(Table, Counter, N) ->
+ ets:insert(Table, [{Counter, N+1}]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race6.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race6.erl
new file mode 100644
index 0000000000..ec0a0eaadf
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_diff_atoms_race6.erl
@@ -0,0 +1,22 @@
+%% This tests that the race condition detection between ets:lookup/
+%% ets:insert is robust even when the functions are called with
+%% different atoms as arguments.
+
+-module(ets_insert_diff_atoms_race6).
+-export([test/0]).
+
+test() ->
+ ets:new(foo, [named_table, public]),
+ {race(foo, counter), no_race(foo, counter)}.
+
+race(Tab, Counter) ->
+ [{_, N}] = ets:lookup(Tab, Counter),
+ aux(Tab, Counter, N).
+
+no_race(Tab, Counter) ->
+ [{_, N}] = ets:lookup(Tab, Counter),
+ AnotherCounter = index,
+ aux(Tab, AnotherCounter, N).
+
+aux(Table, Counter, N) ->
+ ets:insert(Table, {Counter, N+1}).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_double1.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_double1.erl
new file mode 100644
index 0000000000..d5b6689eb1
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_double1.erl
@@ -0,0 +1,28 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account multiple ets:inserts that might exist.
+
+-module(ets_insert_double1).
+-export([start/0]).
+
+start() ->
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {random, random:uniform(150)}),
+ io:format("Inserted ~w\n", [{_, N}] = ets:lookup(foo, random)),
+ case (N rem 2 == 0) of
+ true ->
+ io:format("\nInserted an even integer\n", []),
+ io:format("\nWill make it odd and generate new password\n", []),
+ ets:insert(foo, [{random, N+1}, {pass, generate_password(N)}]);
+ false ->
+ io:format("\nInserted an odd integer\n", []),
+ io:format("\nWill make it even and generate new password\n", []),
+ ets:insert(foo, [{random, N+1}, {pass, generate_password(N)}])
+ end,
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, pass),
+ io:format("New password: ~w\n", [ObjectList]),
+ ets:insert(foo, {pass, 'empty'}).
+
+generate_password(N) ->
+ [{_, P}] = ets:lookup(foo, pass),
+ lists:map(fun (_) -> random:uniform(90)+P+$\s+1 end, lists:seq(1,N)).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_double2.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_double2.erl
new file mode 100644
index 0000000000..fa653e3090
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_double2.erl
@@ -0,0 +1,28 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account multiple ets:inserts that might exist.
+
+-module(ets_insert_double2).
+-export([start/2]).
+
+start(Random, Pass) ->
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {Random, random:uniform(150)}),
+ io:format("Inserted ~w\n", [{_, N}] = ets:lookup(foo, Random)),
+ case (N rem 2 == 0) of
+ true ->
+ io:format("\nInserted an even integer\n", []),
+ io:format("\nWill make it odd and generate new password\n", []),
+ ets:insert(foo, [{Random, N+1}, {Pass, generate_password(Pass, N)}]);
+ false ->
+ io:format("\nInserted an odd integer\n", []),
+ io:format("\nWill make it even and generate new password\n", []),
+ ets:insert(foo, [{Random, N+1}, {Pass, generate_password(Pass, N)}])
+ end,
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, Pass),
+ io:format("New password: ~w\n", [ObjectList]),
+ ets:insert(foo, {Pass, 'empty'}).
+
+generate_password(Pass, N) ->
+ [{_, P}] = ets:lookup(foo, Pass),
+ lists:map(fun (_) -> random:uniform(90)+P+$\s+1 end, lists:seq(1,N)).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_funs1.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_funs1.erl
new file mode 100644
index 0000000000..b6b258fd21
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_funs1.erl
@@ -0,0 +1,18 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account the anonymous functions.
+
+-module(ets_insert_funs1).
+-export([start/0]).
+
+start() ->
+ F = fun(T) ->
+ ets:lookup(T, counter)
+ end,
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {counter, 0}),
+ io:format("Inserted ~w\n", [{counter, 0}]),
+ [{_, N}] = F(foo),
+ ets:insert(foo, [{counter, N+1}]),
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, counter),
+ io:format("Counter: ~w\n", [ObjectList]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_funs2.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_funs2.erl
new file mode 100644
index 0000000000..6b9518f314
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_funs2.erl
@@ -0,0 +1,18 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account the anonymous functions.
+
+-module(ets_insert_funs2).
+-export([start/0]).
+
+start() ->
+ F = fun(T, N) ->
+ ets:insert(T, [{counter, N+1}])
+ end,
+ io:format("Created ~w\n", [ets:new(foo, [named_table, public])]),
+ ets:insert(foo, {counter, 0}),
+ io:format("Inserted ~w\n", [{counter, 0}]),
+ [{_, N}] = ets:lookup(foo, counter),
+ F(foo, N),
+ io:format("Update complete\n", []),
+ ObjectList = ets:lookup(foo, counter),
+ io:format("Counter: ~w\n", [ObjectList]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_new.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_new.erl
new file mode 100644
index 0000000000..63f3272912
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_new.erl
@@ -0,0 +1,15 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination. It takes into account multiple ets:new calls that might exist.
+
+-module(ets_insert_new).
+-export([test/0]).
+
+test() ->
+ T1 = ets:new(foo, [public]),
+ T2 = ets:new(bar, []),
+ ets:lookup(T2, counter),
+ aux(T1),
+ aux(T2).
+
+aux(Tab) ->
+ ets:insert(Tab, {counter, 1}).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/ets_insert_param.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_param.erl
new file mode 100644
index 0000000000..a479a31792
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_param.erl
@@ -0,0 +1,26 @@
+%% This tests the presence of possible races due to an ets:lookup/ets:insert
+%% combination in higher order functions.
+
+-module(ets_insert_param).
+-export([start/1]).
+
+start(User) ->
+ Table = ets:new(table, [public]),
+ mod:process(Table),
+ [{_, Msg}] = ets:lookup(Table, welcome_msg),
+ case User of
+ root ->
+ ets:insert(Table, {welcome_msg, Msg ++ "root"}),
+ ets:insert(Table, {pass, Pass = generate_password(ets:lookup(Table, pass))
+ ++ generate_strong_password(ets:lookup(Table, pass))});
+ user ->
+ ets:insert(Table, {welcome_msg, Msg ++ "user"}),
+ ets:insert(Table, {pass, Pass = generate_password(ets:lookup(Table, pass))})
+ end,
+ io:format("\nYour new pass is ~w\n", [Pass]).
+
+generate_password([{_, N}]) ->
+ lists:map(fun (_) -> random:uniform(90)+$\s+1 end, lists:seq(1,N)).
+
+generate_strong_password([{_, N}]) ->
+ lists:map(fun (_) -> random:uniform(90)+$\s+1 end, lists:seq(1,(N rem 2) * 5)).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/extract_translations.erl b/lib/dialyzer/test/race_SUITE_data/src/extract_translations.erl
new file mode 100644
index 0000000000..76ffca4676
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/extract_translations.erl
@@ -0,0 +1,293 @@
+%%%----------------------------------------------------------------------
+%%% File : extract_translations.erl
+%%% Author : Sergei Golovan <[email protected]>
+%%% Purpose : Auxiliary tool for interface/messages translators
+%%% Created : 23 Apr 2005 by Sergei Golovan <[email protected]>
+%%% Id : $Id: extract_translations.erl,v 1.1 2009/08/17 09:18:59 maria Exp $
+%%%----------------------------------------------------------------------
+
+-module(extract_translations).
+-author('[email protected]').
+
+-export([start/0]).
+
+-define(STATUS_SUCCESS, 0).
+-define(STATUS_ERROR, 1).
+-define(STATUS_USAGE, 2).
+
+-include_lib("kernel/include/file.hrl").
+
+
+start() ->
+ ets:new(translations, [named_table, public]),
+ ets:new(translations_obsolete, [named_table, public]),
+ ets:new(files, [named_table, public]),
+ ets:new(vars, [named_table, public]),
+ case init:get_plain_arguments() of
+ ["-srcmsg2po", Dir, File] ->
+ print_po_header(File),
+ Status = process(Dir, File, srcmsg2po),
+ halt(Status);
+ ["-unused", Dir, File] ->
+ Status = process(Dir, File, unused),
+ halt(Status);
+ [Dir, File] ->
+ Status = process(Dir, File, used),
+ halt(Status);
+ _ ->
+ print_usage(),
+ halt(?STATUS_USAGE)
+ end.
+
+
+process(Dir, File, Used) ->
+ case load_file(File) of
+ {error, Reason} ->
+ io:format("~s: ~s~n", [File, file:format_error(Reason)]),
+ ?STATUS_ERROR;
+ _ ->
+ FileList = find_src_files(Dir),
+ lists:foreach(
+ fun(F) ->
+ parse_file(Dir, F, Used)
+ end, FileList),
+ case Used of
+ unused ->
+ ets:foldl(fun({Key, _}, _) ->
+ io:format("~p~n", [Key])
+ end, ok, translations);
+ srcmsg2po ->
+ ets:foldl(fun({Key, Trans}, _) ->
+ print_translation_obsolete(Key, Trans)
+ end, ok, translations_obsolete);
+ _ ->
+ ok
+ end,
+ ?STATUS_SUCCESS
+ end.
+
+parse_file(Dir, File, Used) ->
+ ets:delete_all_objects(vars),
+ case epp:parse_file(File, [Dir, filename:dirname(File) | code:get_path()], []) of
+ {ok, Forms} ->
+ lists:foreach(
+ fun(F) ->
+ parse_form(Dir, File, F, Used)
+ end, Forms);
+ _ ->
+ ok
+ end.
+
+parse_form(Dir, File, Form, Used) ->
+ case Form of
+ %%{undefined, Something} ->
+ %% io:format("Undefined: ~p~n", [Something]);
+ {call,
+ _,
+ {remote, _, {atom, _, translate}, {atom, _, translate}},
+ [_, {string, Line, Str}]
+ } ->
+ process_string(Dir, File, Line, Str, Used);
+ {call,
+ _,
+ {remote, _, {atom, _, translate}, {atom, _, translate}},
+ [_, {var, _, Name}]
+ } ->
+ case ets:lookup(vars, Name) of
+ [{_Name, Value, Line}] ->
+ process_string(Dir, File, Line, Value, Used);
+ _ ->
+ ok
+ end;
+ {match,
+ _,
+ {var, _, Name},
+ {string, Line, Value}
+ } ->
+ ets:insert(vars, {Name, Value, Line});
+ L when is_list(L) ->
+ lists:foreach(
+ fun(F) ->
+ parse_form(Dir, File, F, Used)
+ end, L);
+ T when is_tuple(T) ->
+ lists:foreach(
+ fun(F) ->
+ parse_form(Dir, File, F, Used)
+ end, tuple_to_list(T));
+ _ ->
+ ok
+ end.
+
+process_string(_Dir, _File, _Line, "", _Used) ->
+ ok;
+
+process_string(_Dir, File, Line, Str, Used) ->
+ case {ets:lookup(translations, Str), Used} of
+ {[{_Key, _Trans}], unused} ->
+ ets:delete(translations, Str);
+ {[{_Key, _Trans}], used} ->
+ ok;
+ {[{_Key, Trans}], srcmsg2po} ->
+ ets:delete(translations_obsolete, Str),
+ print_translation(File, Line, Str, Trans);
+ {_, used} ->
+ case ets:lookup(files, File) of
+ [{_}] ->
+ ok;
+ _ ->
+ io:format("~n% ~s~n", [File]),
+ ets:insert(files, {File})
+ end,
+ case Str of
+ [] -> ok;
+ _ -> io:format("{~p, \"\"}.~n", [Str])
+ end,
+ ets:insert(translations, {Str, ""});
+ {_, srcmsg2po} ->
+ case ets:lookup(files, File) of
+ [{_}] ->
+ ok;
+ _ ->
+ ets:insert(files, {File})
+ end,
+ ets:insert(translations, {Str, ""}),
+ print_translation(File, Line, Str, "");
+ _ ->
+ ok
+ end.
+
+load_file(File) ->
+ case file:consult(File) of
+ {ok, Terms} ->
+ lists:foreach(
+ fun({Orig, Trans}) ->
+ case Trans of
+ "" ->
+ ok;
+ _ ->
+ ets:insert(translations, {Orig, Trans}),
+ ets:insert(translations_obsolete, {Orig, Trans})
+ end
+ end, Terms);
+ Err ->
+ Err
+ end.
+
+find_src_files(Dir) ->
+ case file:list_dir(Dir) of
+ {ok, FileList} ->
+ recurse_filelist(
+ lists:map(
+ fun(F) ->
+ filename:join(Dir, F)
+ end, FileList));
+ _ ->
+ []
+ end.
+
+recurse_filelist(FileList) ->
+ recurse_filelist(FileList, []).
+
+recurse_filelist([], Acc) ->
+ lists:reverse(Acc);
+
+recurse_filelist([H | T], Acc) ->
+ case file:read_file_info(H) of
+ {ok, #file_info{type = directory}} ->
+ recurse_filelist(T, lists:reverse(find_src_files(H)) ++ Acc);
+ {ok, #file_info{type = regular}} ->
+ case string:substr(H, string:len(H) - 3) of
+ ".erl" ->
+ recurse_filelist(T, [H | Acc]);
+ ".hrl" ->
+ recurse_filelist(T, [H | Acc]);
+ _ ->
+ recurse_filelist(T, Acc)
+ end;
+ _ ->
+ recurse_filelist(T, Acc)
+ end.
+
+
+print_usage() ->
+ io:format(
+ "Usage: extract_translations [-unused] dir file~n"
+ "~n"
+ "Example:~n"
+ " extract_translations . ./msgs/ru.msg~n"
+ ).
+
+
+%%%
+%%% Gettext
+%%%
+
+print_po_header(File) ->
+ MsgProps = get_msg_header_props(File),
+ {Language, [LastT | AddT]} = prepare_props(MsgProps),
+ application:load(ejabberd),
+ {ok, Version} = application:get_key(ejabberd, vsn),
+ print_po_header(Version, Language, LastT, AddT).
+
+get_msg_header_props(File) ->
+ {ok, F} = file:open(File, [read]),
+ Lines = get_msg_header_props(F, []),
+ file:close(F),
+ Lines.
+
+get_msg_header_props(F, Lines) ->
+ String = io:get_line(F, ""),
+ case io_lib:fread("% ", String) of
+ {ok, [], RemString} ->
+ case io_lib:fread("~s", RemString) of
+ {ok, [Key], Value} when Value /= "\n" ->
+ %% The first character in Value is a blankspace:
+ %% And the last characters are 'slash n'
+ ValueClean = string:substr(Value, 2, string:len(Value)-2),
+ get_msg_header_props(F, Lines ++ [{Key, ValueClean}]);
+ _ ->
+ get_msg_header_props(F, Lines)
+ end;
+ _ ->
+ Lines
+ end.
+
+prepare_props(MsgProps) ->
+ Language = proplists:get_value("Language:", MsgProps),
+ Authors = proplists:get_all_values("Author:", MsgProps),
+ {Language, Authors}.
+
+print_po_header(Version, Language, LastTranslator, AdditionalTranslatorsList) ->
+ AdditionalTranslatorsString = build_additional_translators(AdditionalTranslatorsList),
+ HeaderString =
+ "msgid \"\"\n"
+ "msgstr \"\"\n"
+ "\"Project-Id-Version: " ++ Version ++ "\\n\"\n"
+ ++ "\"X-Language: " ++ Language ++ "\\n\"\n"
+ "\"Last-Translator: " ++ LastTranslator ++ "\\n\"\n"
+ ++ AdditionalTranslatorsString ++
+ "\"MIME-Version: 1.0\\n\"\n"
+ "\"Content-Type: text/plain; charset=UTF-8\\n\"\n"
+ "\"Content-Transfer-Encoding: 8bit\\n\"\n",
+ io:format("~s~n", [HeaderString]).
+
+build_additional_translators(List) ->
+ lists:foldl(
+ fun(T, Str) ->
+ Str ++ "\"X-Additional-Translator: " ++ T ++ "\\n\"\n"
+ end,
+ "",
+ List).
+
+print_translation(File, Line, Str, StrT) ->
+ {ok, StrQ, _} = regexp:gsub(Str, "\"", "\\\""),
+ {ok, StrTQ, _} = regexp:gsub(StrT, "\"", "\\\""),
+ io:format("#: ~s:~p~nmsgid \"~s\"~nmsgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
+
+print_translation_obsolete(Str, StrT) ->
+ File = "unknown.erl",
+ Line = 1,
+ {ok, StrQ, _} = regexp:gsub(Str, "\"", "\\\""),
+ {ok, StrTQ, _} = regexp:gsub(StrT, "\"", "\\\""),
+ io:format("#: ~s:~p~n#~~ msgid \"~s\"~n#~~ msgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/mnesia_diff_atoms_race1.erl b/lib/dialyzer/test/race_SUITE_data/src/mnesia_diff_atoms_race1.erl
new file mode 100644
index 0000000000..2f499208a2
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/mnesia_diff_atoms_race1.erl
@@ -0,0 +1,33 @@
+%% This tests that the race condition detection between mnesia:dirty_read/
+%% mnesia:dirty_write is robust even when the functions are called with
+%% different atoms as arguments.
+
+-module(mnesia_diff_atoms_race1).
+-export([test/2]).
+
+-record(employee, {emp_no,
+ name,
+ salary,
+ sex,
+ phone,
+ room_no}).
+
+test(Eno, Raise) ->
+ {race(employee, Eno, Raise), no_race(employee, Eno, Raise)}.
+
+race(Tab, Eno, Raise) ->
+ [E] = mnesia:dirty_read(Tab, Eno),
+ Salary = E#employee.salary + Raise,
+ New = E#employee{salary = Salary},
+ aux(Tab, New).
+
+no_race(Tab, Eno, Raise) ->
+ [E] = mnesia:dirty_read(Tab, Eno),
+ Salary = E#employee.salary + Raise,
+ New = E#employee{salary = Salary},
+ AnotherTab = employer,
+ aux(AnotherTab, New).
+
+
+aux(Table, Record) ->
+ mnesia:dirty_write(Table, Record).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/mnesia_diff_atoms_race2.erl b/lib/dialyzer/test/race_SUITE_data/src/mnesia_diff_atoms_race2.erl
new file mode 100644
index 0000000000..c1dcfbd8f5
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/mnesia_diff_atoms_race2.erl
@@ -0,0 +1,37 @@
+%% This tests that the race condition detection between mnesia:dirty_read/
+%% mnesia:dirty_write is robust even when the functions are called with
+%% different atoms as arguments.
+
+-module(mnesia_diff_atoms_race2).
+-export([test/2]).
+
+-record(employee, {emp_no,
+ name,
+ salary,
+ sex,
+ phone,
+ room_no}).
+
+-record(employer, {emp_no,
+ name,
+ salary,
+ sex,
+ phone,
+ room_no}).
+
+test(Eno, Raise) ->
+ {race(employee, Eno, Raise), no_race(employee, Eno, Raise)}.
+
+race(Tab, Eno, Raise) ->
+ [E] = mnesia:dirty_read(Tab, Eno),
+ Salary = E#employee.salary + Raise,
+ New = E#employee{salary = Salary},
+ aux(New).
+
+no_race(Tab, Eno, Raise) ->
+ [E] = mnesia:dirty_read(Tab, Eno),
+ AnotherRecord = #employer{},
+ aux(AnotherRecord).
+
+aux(Record) ->
+ mnesia:dirty_write(Record).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_one_write_two.erl b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_one_write_two.erl
new file mode 100644
index 0000000000..4ca62deedc
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_one_write_two.erl
@@ -0,0 +1,20 @@
+%% This tests the presence of possible races due to an mnesia:dirty_read/
+%% mnesia:dirty_write combination. It takes into account the argument types
+%% of the calls.
+
+-module(mnesia_dirty_read_one_write_two).
+-export([raise/2]).
+
+-record(employee, {emp_no,
+ name,
+ salary,
+ sex,
+ phone,
+ room_no}).
+
+
+raise(Eno, Raise) ->
+ [E] = mnesia:dirty_read({employee, Eno}),
+ Salary = E#employee.salary + Raise,
+ New = E#employee{salary = Salary},
+ mnesia:dirty_write(employee, New).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_two_write_one.erl b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_two_write_one.erl
new file mode 100644
index 0000000000..e523a03789
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_two_write_one.erl
@@ -0,0 +1,20 @@
+%% This tests the presence of possible races due to an mnesia:dirty_read/
+%% mnesia:dirty_write combination. It takes into account the argument types
+%% of the calls.
+
+-module(mnesia_dirty_read_two_write_one).
+-export([raise/2]).
+
+-record(employee, {emp_no,
+ name,
+ salary,
+ sex,
+ phone,
+ room_no}).
+
+
+raise(Eno, Raise) ->
+ [E] = mnesia:dirty_read(employee, Eno),
+ Salary = E#employee.salary + Raise,
+ New = E#employee{salary = Salary},
+ mnesia:dirty_write(New).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double1.erl b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double1.erl
new file mode 100644
index 0000000000..2bd18e4772
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double1.erl
@@ -0,0 +1,25 @@
+%% This tests the presence of possible races due to an mnesia:dirty_read/
+%% mnesia:dirty_write combination. It takes into account multiple
+%% mnesia:dirty_writes that might exist.
+
+-module(mnesia_dirty_read_write_double1).
+-export([raise/3]).
+
+-record(employee, {emp_no,
+ name,
+ salary,
+ sex,
+ phone,
+ room_no}).
+
+
+raise(Eno, Raise, Room) ->
+ [E] = mnesia:dirty_read(employee, Eno),
+ Salary = E#employee.salary + Raise,
+ New = E#employee{salary = Salary},
+ mnesia:dirty_write(employee, New),
+ move(E, Room).
+
+move(E, Room) ->
+ New = E#employee{room_no = Room},
+ mnesia:dirty_write(employee, New).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double2.erl b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double2.erl
new file mode 100644
index 0000000000..cdbfdc700a
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double2.erl
@@ -0,0 +1,25 @@
+%% This tests the presence of possible races due to an mnesia:dirty_read/
+%% mnesia:dirty_write combination. It takes into account multiple
+%% mnesia:dirty_writes that might exist.
+
+-module(mnesia_dirty_read_write_double2).
+-export([raise/3]).
+
+-record(employee, {emp_no,
+ name,
+ salary,
+ sex,
+ phone,
+ room_no}).
+
+
+raise(Eno, Raise, Room) ->
+ [E] = mnesia:dirty_read({employee, Eno}),
+ Salary = E#employee.salary + Raise,
+ New = E#employee{salary = Salary},
+ mnesia:dirty_write(New),
+ move(E, Room).
+
+move(E, Room) ->
+ New = E#employee{room_no = Room},
+ mnesia:dirty_write(New).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double3.erl b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double3.erl
new file mode 100644
index 0000000000..051524917e
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double3.erl
@@ -0,0 +1,25 @@
+%% This tests the presence of possible races due to an mnesia:dirty_read/
+%% mnesia:dirty_write combination. It takes into account multiple
+%% mnesia:dirty_writes that might exist.
+
+-module(mnesia_dirty_read_write_double3).
+-export([raise/3]).
+
+-record(employee, {emp_no,
+ name,
+ salary,
+ sex,
+ phone,
+ room_no}).
+
+
+raise(Eno, Raise, Room) ->
+ [E] = mnesia:dirty_read({employee, Eno}),
+ Salary = E#employee.salary + Raise,
+ New = E#employee{salary = Salary},
+ mnesia:dirty_write(employee, New),
+ move(E, Room).
+
+move(E, Room) ->
+ New = E#employee{room_no = Room},
+ mnesia:dirty_write(employee, New).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double4.erl b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double4.erl
new file mode 100644
index 0000000000..96752a6045
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_double4.erl
@@ -0,0 +1,25 @@
+%% This tests the presence of possible races due to an mnesia:dirty_read/
+%% mnesia:dirty_write combination. It takes into account multiple
+%% mnesia:dirty_writes that might exist.
+
+-module(mnesia_dirty_read_write_double4).
+-export([raise/3]).
+
+-record(employee, {emp_no,
+ name,
+ salary,
+ sex,
+ phone,
+ room_no}).
+
+
+raise(Eno, Raise, Room) ->
+ [E] = mnesia:dirty_read(employee, Eno),
+ Salary = E#employee.salary + Raise,
+ New = E#employee{salary = Salary},
+ mnesia:dirty_write(New),
+ move(E, Room).
+
+move(E, Room) ->
+ New = E#employee{room_no = Room},
+ mnesia:dirty_write(New).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_one.erl b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_one.erl
new file mode 100644
index 0000000000..aee6433736
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_one.erl
@@ -0,0 +1,20 @@
+%% This tests the presence of possible races due to an mnesia:dirty_read/
+%% mnesia:dirty_write combination. It takes into account the argument types
+%% of the calls.
+
+-module(mnesia_dirty_read_write_one).
+-export([raise/2]).
+
+-record(employee, {emp_no,
+ name,
+ salary,
+ sex,
+ phone,
+ room_no}).
+
+
+raise(Eno, Raise) ->
+ [E] = mnesia:dirty_read({employee, Eno}),
+ Salary = E#employee.salary + Raise,
+ New = E#employee{salary = Salary},
+ mnesia:dirty_write(New).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_two.erl b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_two.erl
new file mode 100644
index 0000000000..037aeddafd
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/mnesia_dirty_read_write_two.erl
@@ -0,0 +1,20 @@
+%% This tests the presence of possible races due to an mnesia:dirty_read/
+%% mnesia:dirty_write combination. It takes into account the argument types
+%% of the calls.
+
+-module(mnesia_dirty_read_write_two).
+-export([raise/2]).
+
+-record(employee, {emp_no,
+ name,
+ salary,
+ sex,
+ phone,
+ room_no}).
+
+
+raise(Eno, Raise) ->
+ [E] = mnesia:dirty_read(employee, Eno),
+ Salary = E#employee.salary + Raise,
+ New = E#employee{salary = Salary},
+ mnesia:dirty_write(employee, New).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow1.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow1.erl
new file mode 100644
index 0000000000..e65f6c3e23
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow1.erl
@@ -0,0 +1,17 @@
+%% This tests the presence of possible races due to a whereis/register
+%% combination. It takes into account control flow that might exist.
+
+-module(whereis_control_flow1).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false -> register(AnAtom, Pid)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow2.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow2.erl
new file mode 100644
index 0000000000..41039482c9
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow2.erl
@@ -0,0 +1,19 @@
+%% This tests the presence of possible races due to a whereis/register
+%% combination. It takes into account control flow that might exist.
+
+-module(whereis_control_flow2).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true ->
+ io:format("self",[]),
+ register(AnAtom, Pid);
+ false -> register(AnAtom, Pid)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow3.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow3.erl
new file mode 100644
index 0000000000..94f8445fad
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow3.erl
@@ -0,0 +1,25 @@
+%% This tests the presence of possible races due to a whereis/register
+%% combination. It takes into account control flow that might exist.
+
+-module(whereis_control_flow3).
+-export([start/3]).
+
+start(AnAtom, Fun, FunName) ->
+ Pid =
+ case FunName of
+ master ->
+ case whereis(AnAtom) of
+ undefined ->
+ spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end;
+ slave ->
+ case whereis(AnAtom) of
+ undefined ->
+ spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end
+ end,
+ register(AnAtom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow4.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow4.erl
new file mode 100644
index 0000000000..2a59760789
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow4.erl
@@ -0,0 +1,29 @@
+%% This tests the presence of possible races due to a whereis/register
+%% combination. It takes into account control flow that might exist.
+
+-module(whereis_control_flow4).
+-export([start/1]).
+
+start(Fun) ->
+ case whereis(maria) of
+ undefined ->
+ Pid1 = spawn(Fun),
+ case Pid1 =:= self() of
+ true ->
+ case whereis(kostis) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ case Pid2 =:= self() of
+ true ->
+ register(maria, Pid1),
+ register(kostis, Pid2);
+ false -> ok
+ end;
+ P when is_pid(P) ->
+ ok
+ end;
+ false -> ok
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow5.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow5.erl
new file mode 100644
index 0000000000..8de9cb2dad
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow5.erl
@@ -0,0 +1,12 @@
+%% This tests the presence of possible races due to a whereis/unregister
+%% combination. It takes into account control flow that might exist.
+
+-module(whereis_control_flow5).
+-export([start/1]).
+
+start(AnAtom) ->
+ case whereis(AnAtom) of
+ undefined -> ok;
+ P when is_pid(P) ->
+ unregister(AnAtom)
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow6.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow6.erl
new file mode 100644
index 0000000000..03c5095a50
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_control_flow6.erl
@@ -0,0 +1,12 @@
+%% This tests the presence of possible races due to a whereis/unregister
+%% combination. It takes into account control flow that might exist.
+
+-module(whereis_control_flow6).
+-export([start/0]).
+
+start() ->
+ case whereis(kostis) of
+ undefined -> ok;
+ P when is_pid(P) ->
+ unregister(kostis)
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_atoms_no_race.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_atoms_no_race.erl
new file mode 100644
index 0000000000..704ee6015d
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_atoms_no_race.erl
@@ -0,0 +1,23 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust even when the functions are called with different atoms
+%% as arguments.
+
+-module(whereis_diff_atoms_no_race).
+-export([test/0]).
+
+test() ->
+ Fun = fun () -> foo end,
+ {no_race(maria, Fun)}.
+
+no_race(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ AnotherAtom = kostis,
+ aux(AnotherAtom, Pid);
+ P when is_pid(P) ->
+ ok
+ end.
+
+aux(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_atoms_race.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_atoms_race.erl
new file mode 100644
index 0000000000..6c834caa0c
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_atoms_race.erl
@@ -0,0 +1,34 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust even when the functions are called with different atoms
+%% as arguments.
+
+-module(whereis_diff_atoms_race).
+-export([test/0]). %, race/1, no_race/1]).
+
+test() ->
+ Fun = fun () -> foo end,
+ {race(maria, Fun), no_race(maria, Fun)}.
+
+race(AnAtom, Fun) ->
+ %AnAtom = maria,
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ aux(AnAtom, Pid);
+ P when is_pid(P) ->
+ ok
+ end.
+
+no_race(AnAtom, Fun) ->
+ %AnAtom = maria,
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ AnotherAtom = kostis,
+ aux(AnotherAtom, Pid);
+ P when is_pid(P) ->
+ ok
+ end.
+
+aux(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1.erl
new file mode 100644
index 0000000000..6a1c197c06
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1.erl
@@ -0,0 +1,22 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions.
+
+-module(whereis_diff_functions1).
+-export([start/2]).
+
+continue(Fun) ->
+ case whereis(master) of
+ undefined ->
+ register(master, spawn(Fun));
+ _ -> ok
+ end.
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ register(AnAtom, Pid);
+ _ ->
+ ok
+ end,
+ continue(Fun).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1_nested.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1_nested.erl
new file mode 100644
index 0000000000..4967dec133
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1_nested.erl
@@ -0,0 +1,23 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions.
+
+-module(whereis_diff_functions1_nested).
+-export([test/2]).
+
+test(AnAtom, Fun) ->
+ start(AnAtom, Fun).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ race1(AnAtom, Pid);
+ P when is_pid(P) ->
+ true
+ end.
+
+race1(Atom, Pid) ->
+ race2(Atom, Pid).
+
+race2(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1_pathsens.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1_pathsens.erl
new file mode 100644
index 0000000000..ff6506eee8
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1_pathsens.erl
@@ -0,0 +1,32 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions.
+%% It takes into account control flow that might exist.
+
+-module(whereis_diff_functions1_pathsens).
+-export([test/1]).
+
+test(FunName) ->
+ start(kostis, mod:function(), FunName).
+
+start(AnAtom, Fun, FunName) ->
+ Pid =
+ case FunName of
+ master ->
+ case whereis(AnAtom) of
+ undefined ->
+ spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end;
+ slave ->
+ case whereis(AnAtom) of
+ undefined ->
+ spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end
+ end,
+ race(AnAtom, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1_twice.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1_twice.erl
new file mode 100644
index 0000000000..dd395bb6d8
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions1_twice.erl
@@ -0,0 +1,30 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having multiple calls in separate functions.
+
+-module(whereis_diff_functions1_twice).
+-export([test/2]).
+
+test(AnAtom, Fun) ->
+ start(AnAtom, Fun).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid1 = spawn(Fun),
+ race(AnAtom, Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ race_again(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end;
+ P when is_pid(P) ->
+ true
+ end.
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
+
+race_again(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2.erl
new file mode 100644
index 0000000000..eaf98291ed
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2.erl
@@ -0,0 +1,25 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions.
+
+-module(whereis_diff_functions2).
+-export([test/0]).
+
+test() ->
+ start(kostis, mod:function()).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ race(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end.
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2_nested.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2_nested.erl
new file mode 100644
index 0000000000..5ae8784389
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2_nested.erl
@@ -0,0 +1,20 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions.
+
+-module(whereis_diff_functions2_nested).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ race1(AnAtom, Pid);
+ P when is_pid(P) ->
+ true
+ end.
+
+race1(Atom, Pid) ->
+ race2(Atom, Pid).
+
+race2(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2_pathsens.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2_pathsens.erl
new file mode 100644
index 0000000000..e9ce4bc48e
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2_pathsens.erl
@@ -0,0 +1,29 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions.
+%% It takes into account control flow that might exist.
+
+-module(whereis_diff_functions2_pathsens).
+-export([race/4]).
+
+start(AnAtom, Fun, FunName) ->
+ Pid =
+ case FunName of
+ master ->
+ case whereis(AnAtom) of
+ undefined ->
+ spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end;
+ slave ->
+ case whereis(AnAtom) of
+ undefined ->
+ spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end
+ end.
+
+race(Atom, Fun, FunName, Pid) ->
+ start(Atom, Fun, FunName),
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2_twice.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2_twice.erl
new file mode 100644
index 0000000000..d5efe631b8
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions2_twice.erl
@@ -0,0 +1,27 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having multiple calls in separate functions.
+
+-module(whereis_diff_functions2_twice).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid1 = spawn(Fun),
+ race(AnAtom, Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ race_again(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end;
+ P when is_pid(P) ->
+ true
+ end.
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
+
+race_again(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions3.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions3.erl
new file mode 100644
index 0000000000..093f02a06f
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions3.erl
@@ -0,0 +1,11 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions.
+
+-module(whereis_diff_functions3).
+-export([start/1]).
+
+start(AnAtom) ->
+ register(AnAtom, race(AnAtom)).
+
+race(Atom) ->
+ whereis(Atom).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions3_nested.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions3_nested.erl
new file mode 100644
index 0000000000..5c28fc74f6
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions3_nested.erl
@@ -0,0 +1,21 @@
+%% This tests that the race condition detection between whereis/unregister
+%% is robust w.r.t. having the calls in separate functions.
+
+-module(whereis_diff_functions3_nested).
+-export([test/1]).
+
+test(AnAtom) ->
+ start(AnAtom).
+
+start(AnAtom) ->
+ case whereis(AnAtom) of
+ undefined -> true;
+ P when is_pid(P) ->
+ race1(AnAtom)
+ end.
+
+race1(Atom) ->
+ race2(Atom).
+
+race2(Atom) ->
+ unregister(Atom).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions3_pathsens.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions3_pathsens.erl
new file mode 100644
index 0000000000..a3a245b9ea
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions3_pathsens.erl
@@ -0,0 +1,29 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions.
+%% It takes into account control flow that might exist.
+
+-module(whereis_diff_functions3_pathsens).
+-export([start/3]).
+
+start(AnAtom, Fun, FunName) ->
+ Pid =
+ case FunName of
+ master ->
+ case whereis(AnAtom) of
+ undefined ->
+ spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end;
+ slave ->
+ case whereis(AnAtom) of
+ undefined ->
+ spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end
+ end,
+ race(AnAtom, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions4.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions4.erl
new file mode 100644
index 0000000000..e40483d487
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions4.erl
@@ -0,0 +1,32 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions.
+
+-module(whereis_diff_functions4).
+-export([test/2]).
+
+test(AnAtom, Fun) ->
+ start(AnAtom, Fun).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ race(AnAtom, Pid2),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid3 = spawn(Fun),
+ race(AnAtom, Pid3);
+ P when is_pid(P) ->
+ true
+ end;
+ P when is_pid(P) ->
+ true
+ end.
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions5.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions5.erl
new file mode 100644
index 0000000000..a2c4352803
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions5.erl
@@ -0,0 +1,22 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions.
+
+-module(whereis_diff_functions5).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ race(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end.
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions6.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions6.erl
new file mode 100644
index 0000000000..f016d79533
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_functions6.erl
@@ -0,0 +1,29 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions.
+
+-module(whereis_diff_functions6).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ race(AnAtom, Pid2),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid3 = spawn(Fun),
+ race(AnAtom, Pid3);
+ P when is_pid(P) ->
+ true
+ end;
+ P when is_pid(P) ->
+ true
+ end.
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1/whereis_diff_modules1.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1/whereis_diff_modules1.erl
new file mode 100644
index 0000000000..00cb29cec0
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1/whereis_diff_modules1.erl
@@ -0,0 +1,16 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules.
+
+-module(whereis_diff_modules1).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ whereis_diff_modules2:no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ whereis_diff_modules2:race(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1/whereis_diff_modules2.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1/whereis_diff_modules2.erl
new file mode 100644
index 0000000000..e5f6fdeb7b
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1/whereis_diff_modules2.erl
@@ -0,0 +1,11 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules.
+
+-module(whereis_diff_modules2).
+-export([no_race/1, race/2]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_pathsens/whereis_diff_modules1_pathsens.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_pathsens/whereis_diff_modules1_pathsens.erl
new file mode 100644
index 0000000000..a5f1d4d3c7
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_pathsens/whereis_diff_modules1_pathsens.erl
@@ -0,0 +1,26 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules (backward analysis).
+%% It takes into account control flow that might exist.
+
+-module(whereis_diff_modules1_pathsens).
+-export([start/3]).
+
+start(AnAtom, Fun, FunName) ->
+ Pid =
+ case FunName of
+ master ->
+ case whereis(AnAtom) of
+ undefined ->
+ spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end;
+ slave ->
+ case whereis(AnAtom) of
+ undefined ->
+ spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end
+ end,
+ whereis_diff_modules2_pathsens:race(AnAtom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_pathsens/whereis_diff_modules2_pathsens.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_pathsens/whereis_diff_modules2_pathsens.erl
new file mode 100644
index 0000000000..d24d13976b
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_pathsens/whereis_diff_modules2_pathsens.erl
@@ -0,0 +1,12 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules (backward analysis).
+%% It takes into account control flow that might exist.
+
+-module(whereis_diff_modules2_pathsens).
+-export([no_race/1, race/2]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_rec/whereis_diff_modules1_rec.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_rec/whereis_diff_modules1_rec.erl
new file mode 100644
index 0000000000..a397954eea
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_rec/whereis_diff_modules1_rec.erl
@@ -0,0 +1,22 @@
+%% This tests the presence of possible races due to a register/whereis
+%% combination in an indirectly recursive inter-modular function.
+
+-module(whereis_diff_modules1_rec).
+-export([start/4]).
+
+start(AnAtom, NextAtom, Fun, Id) ->
+ case AnAtom of
+ undefined -> register(start, Id);
+ _ -> register(AnAtom, Id)
+ end,
+ case whereis(NextAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ whereis_diff_modules2_rec:continue(NextAtom, mod:next(), Pid, Id)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_rec/whereis_diff_modules2_rec.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_rec/whereis_diff_modules2_rec.erl
new file mode 100644
index 0000000000..4b46b4a8e5
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules1_rec/whereis_diff_modules2_rec.erl
@@ -0,0 +1,8 @@
+%% This tests the presence of possible races due to a register/whereis
+%% combination in a recursive function.
+
+-module(whereis_diff_modules2_rec).
+-export([continue/4]).
+
+continue(Atom, NextAtom, Fun, Id) ->
+ whereis_diff_modules1_rec:start(Atom, NextAtom, Fun, Id).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2/whereis_diff_modules3.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2/whereis_diff_modules3.erl
new file mode 100644
index 0000000000..60b5a1d378
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2/whereis_diff_modules3.erl
@@ -0,0 +1,8 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules.
+
+-module(whereis_diff_modules3).
+-export([start/1]).
+
+start(AnAtom) ->
+ register(AnAtom, whereis_diff_modules4:race(AnAtom)).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2/whereis_diff_modules4.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2/whereis_diff_modules4.erl
new file mode 100644
index 0000000000..1ab4fbf8d8
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2/whereis_diff_modules4.erl
@@ -0,0 +1,11 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules.
+
+-module(whereis_diff_modules4).
+-export([no_race/1, race/1]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom) ->
+ whereis(Atom).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_pathsens/whereis_diff_modules3_pathsens.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_pathsens/whereis_diff_modules3_pathsens.erl
new file mode 100644
index 0000000000..cb2f85a103
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_pathsens/whereis_diff_modules3_pathsens.erl
@@ -0,0 +1,25 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules (forward analysis).
+%% It takes into account control flow that might exist.
+
+-module(whereis_diff_modules3_pathsens).
+-export([start/3]).
+
+start(AnAtom, Fun, FunName) ->
+ Pid =
+ case FunName of
+ master ->
+ case whereis(AnAtom) of
+ undefined ->
+ spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end;
+ slave ->
+ case whereis(AnAtom) of
+ undefined ->
+ spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_pathsens/whereis_diff_modules4_pathsens.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_pathsens/whereis_diff_modules4_pathsens.erl
new file mode 100644
index 0000000000..952f9312f4
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_pathsens/whereis_diff_modules4_pathsens.erl
@@ -0,0 +1,13 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules (forward analysis).
+%% It takes into account control flow that might exist.
+
+-module(whereis_diff_modules4_pathsens).
+-export([no_race/1, race/4]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Fun, FunName, Pid) ->
+ whereis_diff_modules3_pathsens:start(Atom, Fun, FunName),
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_rec/whereis_diff_modules3_rec.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_rec/whereis_diff_modules3_rec.erl
new file mode 100644
index 0000000000..0320140768
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_rec/whereis_diff_modules3_rec.erl
@@ -0,0 +1,25 @@
+%% This tests the presence of possible races due to a register/whereis
+%% combination in an indirectly recursive inter-modular function.
+
+-module(whereis_diff_modules3_rec).
+-export([test/0, start/4]).
+
+test() ->
+ start(undefined, second, mod:f(), self()).
+
+start(AnAtom, NextAtom, Fun, Id) ->
+ case AnAtom of
+ undefined -> register(start, Id);
+ _ -> register(AnAtom, Id)
+ end,
+ case whereis(NextAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ whereis_diff_modules4_rec:continue(NextAtom, mod:next(), Pid, Id)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_rec/whereis_diff_modules4_rec.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_rec/whereis_diff_modules4_rec.erl
new file mode 100644
index 0000000000..d49c59ed5c
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules2_rec/whereis_diff_modules4_rec.erl
@@ -0,0 +1,8 @@
+%% This tests the presence of possible races due to a register/whereis
+%% combination in a recursive function.
+
+-module(whereis_diff_modules4_rec).
+-export([continue/4]).
+
+continue(Atom, NextAtom, Fun, Id) ->
+ whereis_diff_modules3_rec:start(Atom, NextAtom, Fun, Id).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules3/whereis_diff_modules5.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules3/whereis_diff_modules5.erl
new file mode 100644
index 0000000000..591732aa31
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules3/whereis_diff_modules5.erl
@@ -0,0 +1,23 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules.
+
+-module(whereis_diff_modules5).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ whereis_diff_modules6:no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ whereis_diff_modules6:race(AnAtom, Pid2),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid3 = spawn(Fun),
+ whereis_diff_modules6:race(AnAtom, Pid3);
+ P when is_pid(P) ->
+ true
+ end;
+ P when is_pid(P) ->
+ true
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules3/whereis_diff_modules6.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules3/whereis_diff_modules6.erl
new file mode 100644
index 0000000000..159d96cfc5
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules3/whereis_diff_modules6.erl
@@ -0,0 +1,11 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules.
+
+-module(whereis_diff_modules6).
+-export([no_race/1, race/2]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_nested/whereis_diff_modules1_nested.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_nested/whereis_diff_modules1_nested.erl
new file mode 100644
index 0000000000..a25d2f8784
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_nested/whereis_diff_modules1_nested.erl
@@ -0,0 +1,14 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules.
+
+-module(whereis_diff_modules1_nested).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ whereis_diff_modules2_nested:race(AnAtom, Pid);
+ P when is_pid(P) ->
+ true
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_nested/whereis_diff_modules2_nested.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_nested/whereis_diff_modules2_nested.erl
new file mode 100644
index 0000000000..32a55e731a
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_nested/whereis_diff_modules2_nested.erl
@@ -0,0 +1,11 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules.
+
+-module(whereis_diff_modules2_nested).
+-export([no_race/1, race/2]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ whereis_diff_modules3_nested:race(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_nested/whereis_diff_modules3_nested.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_nested/whereis_diff_modules3_nested.erl
new file mode 100644
index 0000000000..414129611f
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_nested/whereis_diff_modules3_nested.erl
@@ -0,0 +1,11 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules.
+
+-module(whereis_diff_modules3_nested).
+-export([no_race/1, race/2]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_twice/whereis_diff_modules1_twice.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_twice/whereis_diff_modules1_twice.erl
new file mode 100644
index 0000000000..92f2cb1fbc
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_twice/whereis_diff_modules1_twice.erl
@@ -0,0 +1,21 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having multiple calls in separate modules.
+
+-module(whereis_diff_modules1_twice).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid1 = spawn(Fun),
+ whereis_diff_modules2_twice:race(AnAtom, Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ whereis_diff_modules2_twice:race_again(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end;
+ P when is_pid(P) ->
+ true
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_twice/whereis_diff_modules2_twice.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_twice/whereis_diff_modules2_twice.erl
new file mode 100644
index 0000000000..390c0dcc94
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_modules_twice/whereis_diff_modules2_twice.erl
@@ -0,0 +1,11 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate modules.
+
+-module(whereis_diff_modules2_twice).
+-export([race/2, race_again/2]).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
+
+race_again(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_vars_no_race.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_vars_no_race.erl
new file mode 100644
index 0000000000..8466004ce4
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_vars_no_race.erl
@@ -0,0 +1,13 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust even when the functions are called with different variables
+%% as arguments.
+
+-module(whereis_diff_vars_no_race).
+-export([test/3]).
+
+test(AnAtom, AnotherAtom, Pid) ->
+ {aux(AnAtom, Pid), aux(AnotherAtom, Pid)}.
+
+aux(Atom, Pid) ->
+ register(Atom, Pid),
+ whereis(Atom).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_vars_race.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_vars_race.erl
new file mode 100644
index 0000000000..90791de1b2
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_diff_vars_race.erl
@@ -0,0 +1,19 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust even when the functions are called with different variables
+%% as arguments.
+
+-module(whereis_diff_vars_race).
+-export([test/2]).
+
+test(AnAtom, AnotherAtom) ->
+ Fun = fun () -> foo end,
+ {aux(AnAtom, AnotherAtom, Fun), aux(AnotherAtom, AnAtom, Fun)}.
+
+aux(Atom1, Atom2, Fun) ->
+ case whereis(Atom1) of
+ undefined ->
+ Pid = spawn(Fun),
+ register(Atom2, Pid);
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module1/whereis_intra_inter_module1.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module1/whereis_intra_inter_module1.erl
new file mode 100644
index 0000000000..677551c99d
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module1/whereis_intra_inter_module1.erl
@@ -0,0 +1,19 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module1).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ whereis_intra_inter_module2:no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ continue(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end.
+
+continue(Atom, Pid) ->
+ whereis_intra_inter_module2:race(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module1/whereis_intra_inter_module2.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module1/whereis_intra_inter_module2.erl
new file mode 100644
index 0000000000..e7acee0cfd
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module1/whereis_intra_inter_module2.erl
@@ -0,0 +1,11 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module2).
+-export([no_race/1, race/2]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module2/whereis_intra_inter_module3.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module2/whereis_intra_inter_module3.erl
new file mode 100644
index 0000000000..c8103db122
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module2/whereis_intra_inter_module3.erl
@@ -0,0 +1,16 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module3).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ whereis_intra_inter_module4:no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ whereis_intra_inter_module4:race(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module2/whereis_intra_inter_module4.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module2/whereis_intra_inter_module4.erl
new file mode 100644
index 0000000000..4094a95223
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module2/whereis_intra_inter_module4.erl
@@ -0,0 +1,14 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module4).
+-export([no_race/1, race/2]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ continue(Atom, Pid).
+
+continue(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module3/whereis_intra_inter_module5.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module3/whereis_intra_inter_module5.erl
new file mode 100644
index 0000000000..2a29779153
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module3/whereis_intra_inter_module5.erl
@@ -0,0 +1,19 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module5).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ whereis_intra_inter_module6:no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ continue(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end.
+
+continue(Atom, Pid) ->
+ whereis_intra_inter_module6:race(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module3/whereis_intra_inter_module6.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module3/whereis_intra_inter_module6.erl
new file mode 100644
index 0000000000..cd05431cd5
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module3/whereis_intra_inter_module6.erl
@@ -0,0 +1,14 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module6).
+-export([no_race/1, race/2]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ continue(Atom, Pid).
+
+continue(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module4/whereis_intra_inter_module7.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module4/whereis_intra_inter_module7.erl
new file mode 100644
index 0000000000..1f702e7af3
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module4/whereis_intra_inter_module7.erl
@@ -0,0 +1,11 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module7).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ register(AnAtom, continue(AnAtom, Fun)).
+
+continue(AnAtom, Fun) ->
+ whereis_intra_inter_module8:continue(AnAtom, Fun).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module4/whereis_intra_inter_module8.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module4/whereis_intra_inter_module8.erl
new file mode 100644
index 0000000000..581817308b
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module4/whereis_intra_inter_module8.erl
@@ -0,0 +1,13 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module8).
+-export([continue/2]).
+
+continue(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module5/whereis_intra_inter_module10.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module5/whereis_intra_inter_module10.erl
new file mode 100644
index 0000000000..7ed50ea742
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module5/whereis_intra_inter_module10.erl
@@ -0,0 +1,16 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module10).
+-export([continue/2]).
+
+continue(AnAtom, Fun) ->
+ aux(AnAtom, Fun).
+
+aux(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module5/whereis_intra_inter_module9.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module5/whereis_intra_inter_module9.erl
new file mode 100644
index 0000000000..5c5d92b770
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module5/whereis_intra_inter_module9.erl
@@ -0,0 +1,11 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module9).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ register(AnAtom, continue(AnAtom, Fun)).
+
+continue(AnAtom, Fun) ->
+ whereis_intra_inter_module10:continue(AnAtom, Fun).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module6/whereis_intra_inter_module11.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module6/whereis_intra_inter_module11.erl
new file mode 100644
index 0000000000..82abe2f4a8
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module6/whereis_intra_inter_module11.erl
@@ -0,0 +1,27 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module11).
+-export([start/2, start_again/2]).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ whereis_intra_inter_module12:no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ whereis_intra_inter_module12:race(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end.
+
+start_again(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ whereis_intra_inter_module12:no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ whereis_intra_inter_module12:continue(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module6/whereis_intra_inter_module12.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module6/whereis_intra_inter_module12.erl
new file mode 100644
index 0000000000..c2f5d560a0
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module6/whereis_intra_inter_module12.erl
@@ -0,0 +1,14 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module12).
+-export([no_race/1, race/2, continue/2]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ continue(Atom, Pid).
+
+continue(Atom, Pid) ->
+ register(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module7/whereis_intra_inter_module13.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module7/whereis_intra_inter_module13.erl
new file mode 100644
index 0000000000..3cd5cc6fa6
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module7/whereis_intra_inter_module13.erl
@@ -0,0 +1,19 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module13).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ whereis_intra_inter_module14:no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ continue(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end.
+
+continue(Atom, Pid) ->
+ whereis_intra_inter_module14:race(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module7/whereis_intra_inter_module14.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module7/whereis_intra_inter_module14.erl
new file mode 100644
index 0000000000..6b6a982055
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module7/whereis_intra_inter_module14.erl
@@ -0,0 +1,22 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module14).
+-export([no_race/1, race/2, start/2]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ race(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module8/whereis_intra_inter_module15.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module8/whereis_intra_inter_module15.erl
new file mode 100644
index 0000000000..c60d166fa9
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module8/whereis_intra_inter_module15.erl
@@ -0,0 +1,19 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module15).
+-export([start/2, continue/2]).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ whereis_intra_inter_module16:no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ continue(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end.
+
+continue(Atom, Pid) ->
+ whereis_intra_inter_module16:race(Atom, Pid).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module8/whereis_intra_inter_module16.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module8/whereis_intra_inter_module16.erl
new file mode 100644
index 0000000000..279e633d66
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_intra_inter_module8/whereis_intra_inter_module16.erl
@@ -0,0 +1,22 @@
+%% This tests that the race condition detection between whereis/register
+%% is robust w.r.t. having the calls in separate functions and modules.
+
+-module(whereis_intra_inter_module16).
+-export([no_race/1, race/2, start/2]).
+
+no_race(Pid) ->
+ register(master, Pid).
+
+race(Atom, Pid) ->
+ register(Atom, Pid).
+
+start(AnAtom, Fun) ->
+ Pid1 = spawn(Fun),
+ no_race(Pid1),
+ case whereis(AnAtom) of
+ undefined ->
+ Pid2 = spawn(Fun),
+ whereis_intra_inter_module15:continue(AnAtom, Pid2);
+ P when is_pid(P) ->
+ true
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_param.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_param.erl
new file mode 100644
index 0000000000..7bcde321a1
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_param.erl
@@ -0,0 +1,16 @@
+%% This tests the presence of possible races due to a whereis/register
+%% combination in higher order functions.
+
+-module(whereis_param).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ register(AnAtom, continue(AnAtom, Fun)).
+
+continue(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_param_inter_module/whereis_param_inter_module1.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_param_inter_module/whereis_param_inter_module1.erl
new file mode 100644
index 0000000000..8bac0326a5
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_param_inter_module/whereis_param_inter_module1.erl
@@ -0,0 +1,8 @@
+%% This tests the presence of possible races due to a whereis/register
+%% combination in higher order functions and inter-module calls.
+
+-module(whereis_param_inter_module1).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ register(AnAtom, whereis_param_inter_module2:continue(AnAtom, Fun)).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_param_inter_module/whereis_param_inter_module2.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_param_inter_module/whereis_param_inter_module2.erl
new file mode 100644
index 0000000000..61252add9a
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_param_inter_module/whereis_param_inter_module2.erl
@@ -0,0 +1,13 @@
+%% This tests the presence of possible races due to a whereis/register
+%% combination in higher order functions and inter-module calls.
+
+-module(whereis_param_inter_module2).
+-export([continue/2]).
+
+continue(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun);
+ P when is_pid(P) ->
+ P
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function1.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function1.erl
new file mode 100644
index 0000000000..c8095fbf4c
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function1.erl
@@ -0,0 +1,19 @@
+%% This tests the presence of possible races due to a whereis/register
+%% combination in a recursive function.
+
+-module(whereis_rec_function1).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ register(AnAtom, Pid),
+ start(AnAtom, Fun)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function2.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function2.erl
new file mode 100644
index 0000000000..2721c9e19c
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function2.erl
@@ -0,0 +1,24 @@
+%% This tests the presence of possible races due to a register/whereis
+%% combination in a recursive function.
+
+-module(whereis_rec_function2).
+-export([test/0]).
+
+test() ->
+ start(undefined, second, mod:f(), self()).
+
+start(AnAtom, NextAtom, Fun, Id) ->
+ case AnAtom of
+ undefined -> register(start, Id);
+ _ -> register(AnAtom, Id)
+ end,
+ case whereis(NextAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false -> start(NextAtom, mod:next(), Pid, Id)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function3.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function3.erl
new file mode 100644
index 0000000000..e101f34fba
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function3.erl
@@ -0,0 +1,27 @@
+%% This tests the presence of possible races due to a register/whereis
+%% combination in a recursive function.
+
+-module(whereis_rec_function3).
+-export([test/0]).
+
+test() ->
+ start(undefined, second, mod:f(), self()).
+
+start(AnAtom, NextAtom, Fun, Id) ->
+ case AnAtom of
+ undefined -> register(start, Id);
+ _ -> register(AnAtom, Id)
+ end,
+ Pid =
+ case whereis(NextAtom) of
+ undefined -> spawn(Fun);
+ P1 when is_pid(P1) -> P1
+ end,
+ case whereis(NextAtom) of
+ undefined ->
+ case Pid =:= self() of
+ true -> ok;
+ false -> start(NextAtom, mod:next(), Pid, Id), io:format("", [])
+ end;
+ P2 when is_pid(P2) -> ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function4.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function4.erl
new file mode 100644
index 0000000000..4894d3397b
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function4.erl
@@ -0,0 +1,27 @@
+%% This tests the presence of possible races due to a register/whereis
+%% combination in an indirectly recursive function.
+
+-module(whereis_rec_function4).
+-export([test/0]).
+
+test() ->
+ start(undefined, second, mod:f(), self()).
+
+start(AnAtom, NextAtom, Fun, Id) ->
+ case AnAtom of
+ undefined -> register(start, Id);
+ _ -> register(AnAtom, Id)
+ end,
+ case whereis(NextAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false -> continue(NextAtom, mod:next(), Pid, Id)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
+
+continue(Atom, NextAtom, Fun, Id) ->
+ start(Atom, NextAtom, Fun, Id).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function5.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function5.erl
new file mode 100644
index 0000000000..d821f829a2
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function5.erl
@@ -0,0 +1,21 @@
+%% This tests the presence of possible races due to a register/whereis
+%% combination in a recursive function.
+
+-module(whereis_rec_function5).
+-export([start/4]).
+
+start(AnAtom, NextAtom, Fun, Id) ->
+ case AnAtom of
+ undefined -> register(start, Id);
+ _ -> register(AnAtom, Id)
+ end,
+ case whereis(NextAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false -> start(NextAtom, mod:next(), Pid, Id)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function6.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function6.erl
new file mode 100644
index 0000000000..4ec4baf0be
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function6.erl
@@ -0,0 +1,24 @@
+%% This tests the presence of possible races due to a register/whereis
+%% combination in an indirectly recursive function.
+
+-module(whereis_rec_function6).
+-export([start/4]).
+
+start(AnAtom, NextAtom, Fun, Id) ->
+ case AnAtom of
+ undefined -> register(start, Id);
+ _ -> register(AnAtom, Id)
+ end,
+ case whereis(NextAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false -> continue(NextAtom, mod:next(), Pid, Id)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
+
+continue(Atom, NextAtom, Fun, Id) ->
+ start(Atom, NextAtom, Fun, Id).
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function7.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function7.erl
new file mode 100644
index 0000000000..7667443117
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function7.erl
@@ -0,0 +1,19 @@
+%% This tests the presence of possible races due to a whereis/register
+%% combination in a recursive function.
+
+-module(whereis_rec_function7).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ start(AnAtom, Fun),
+ register(AnAtom, Pid)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function8.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function8.erl
new file mode 100644
index 0000000000..a06fb75f64
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_rec_function8.erl
@@ -0,0 +1,22 @@
+%% This tests the presence of possible races due to a whereis/register
+%% combination in a recursive function.
+
+-module(whereis_rec_function8).
+-export([test/2]).
+
+test(AnAtom, Fun) ->
+ start(AnAtom, Fun).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ start(AnAtom, Fun),
+ register(AnAtom, Pid)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_try_catch.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_try_catch.erl
new file mode 100644
index 0000000000..39bb440f56
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_try_catch.erl
@@ -0,0 +1,25 @@
+% This tests that warnings do appear when a whereis/register combination
+% is handled by try/catch.
+
+-module(whereis_try_catch).
+-export([race/1, no_race/1]).
+
+race(Pid) ->
+ case whereis(master) of
+ undefined ->
+ try
+ io:format("exception", [])
+ catch
+ _ -> register(master, Pid)
+ end
+ end.
+
+no_race(Pid) ->
+ case whereis(master) of
+ undefined ->
+ try
+ register(master, Pid)
+ catch
+ _ -> io:format("exception", [])
+ end
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars1.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars1.erl
new file mode 100644
index 0000000000..9b249e72be
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars1.erl
@@ -0,0 +1,17 @@
+%% This tests that no warnings appear when there is no specific
+%% information about the types and the variables are not bound.
+
+-module(whereis_vars1).
+-export([start/3]).
+
+start(AnAtom, OtherAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false -> register(OtherAtom, Pid)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars10.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars10.erl
new file mode 100644
index 0000000000..5c1896d6b4
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars10.erl
@@ -0,0 +1,22 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars10).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case AnAtom =/= OtherAtom of
+ true -> ok;
+ false -> register(OtherAtom, Pid)
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars11.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars11.erl
new file mode 100644
index 0000000000..dc8551b3f2
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars11.erl
@@ -0,0 +1,22 @@
+%% This tests that no warnings appear when there is no specific
+%% information about the types and the variables are not bound.
+
+-module(whereis_vars11).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case AnAtom of
+ OtherAtom -> ok;
+ _Other -> register(OtherAtom, Pid)
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars12.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars12.erl
new file mode 100644
index 0000000000..38b0dc5d04
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars12.erl
@@ -0,0 +1,22 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars12).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ if
+ AnAtom =:= OtherAtom -> register(OtherAtom, Pid);
+ AnAtom =/= OtherAtom -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars13.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars13.erl
new file mode 100644
index 0000000000..3a04bba02f
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars13.erl
@@ -0,0 +1,22 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars13).
+-export([start/3]).
+
+start(AnAtom, APid, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ if
+ {AnAtom, Pid} =:= {OtherAtom, APid} -> register(OtherAtom, APid);
+ {AnAtom, Pid} =/= {OtherAtom, APid} -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars14.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars14.erl
new file mode 100644
index 0000000000..c688847551
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars14.erl
@@ -0,0 +1,22 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars14).
+-export([start/3]).
+
+start(AnAtom, APid, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ if
+ [AnAtom, Pid] =:= [OtherAtom, APid] -> register(OtherAtom, APid);
+ [AnAtom, Pid] =/= [OtherAtom, APid] -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars15.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars15.erl
new file mode 100644
index 0000000000..4b3a72537e
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars15.erl
@@ -0,0 +1,23 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars15).
+-export([start/3]).
+
+start(AnAtom, OtherAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case AnAtom of
+ maria -> ok;
+ kostis when AnAtom =:= OtherAtom ->
+ register(OtherAtom, Pid);
+ _Other -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars16.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars16.erl
new file mode 100644
index 0000000000..7badb8df22
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars16.erl
@@ -0,0 +1,23 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars16).
+-export([start/4]).
+
+start(AnAtom, OtherAtom, APid, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case AnAtom of
+ maria -> ok;
+ kostis when {AnAtom, Pid} =:= {OtherAtom, APid} ->
+ register(OtherAtom, APid);
+ _Other -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars17.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars17.erl
new file mode 100644
index 0000000000..bc7ef5e980
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars17.erl
@@ -0,0 +1,23 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars17).
+-export([start/4]).
+
+start(AnAtom, OtherAtom, APid, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case AnAtom of
+ maria -> ok;
+ kostis when [AnAtom, Pid] =:= [OtherAtom, APid] ->
+ register(OtherAtom, APid);
+ _Other -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars18.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars18.erl
new file mode 100644
index 0000000000..06416fa987
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars18.erl
@@ -0,0 +1,22 @@
+%% This tests that no warnings appear when there is no specific
+%% information about the types and the variables are not bound.
+
+-module(whereis_vars18).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case AnAtom =:= OtherAtom of
+ true -> ok;
+ false -> register(OtherAtom, Pid)
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars19.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars19.erl
new file mode 100644
index 0000000000..ae5b28e42d
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars19.erl
@@ -0,0 +1,23 @@
+%% This tests that no warnings appear when there is no specific
+%% information about the types and the variables are not bound.
+
+-module(whereis_vars19).
+-export([start/3]).
+
+start(AnAtom, OtherAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case AnAtom of
+ maria -> ok;
+ kostis when AnAtom =/= OtherAtom ->
+ register(OtherAtom, Pid);
+ _Other -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars2.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars2.erl
new file mode 100644
index 0000000000..bafb5d4644
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars2.erl
@@ -0,0 +1,18 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars2).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = AnAtom,
+ case Pid =:= self() of
+ true -> ok;
+ false -> register(OtherAtom, Pid)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars20.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars20.erl
new file mode 100644
index 0000000000..87c6caadf0
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars20.erl
@@ -0,0 +1,22 @@
+%% This tests that no warnings appear when there is no specific
+%% information about the types and the variables are not bound.
+
+-module(whereis_vars20).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ if
+ AnAtom =:= OtherAtom -> ok;
+ AnAtom =/= OtherAtom -> register(OtherAtom, Pid)
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars21.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars21.erl
new file mode 100644
index 0000000000..73d22d3467
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars21.erl
@@ -0,0 +1,23 @@
+%% This tests that no warnings appear when there is no specific
+%% information about the types and the variables are not bound.
+
+-module(whereis_vars21).
+-export([start/3]).
+
+start(AnAtom, OtherAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case AnAtom of
+ maria when AnAtom =/= OtherAtom -> ok;
+ kostis when AnAtom =/= OtherAtom ->
+ register(OtherAtom, Pid);
+ _Other -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars22.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars22.erl
new file mode 100644
index 0000000000..dd16928e33
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars22.erl
@@ -0,0 +1,27 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars22).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ Same =
+ case AnAtom of
+ OtherAtom -> true;
+ _Other -> false
+ end,
+ case Same of
+ true -> register(OtherAtom, Pid);
+ false -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars3.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars3.erl
new file mode 100644
index 0000000000..16c9a6c8bc
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars3.erl
@@ -0,0 +1,18 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars3).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ {OtherAtom, APid} = {AnAtom, Pid},
+ case Pid =:= self() of
+ true -> ok;
+ false -> register(OtherAtom, APid)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars4.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars4.erl
new file mode 100644
index 0000000000..da5b329ca9
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars4.erl
@@ -0,0 +1,18 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars4).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ [OtherAtom, APid] = [AnAtom, Pid],
+ case Pid =:= self() of
+ true -> ok;
+ false -> register(OtherAtom, APid)
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars5.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars5.erl
new file mode 100644
index 0000000000..dff8646ea8
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars5.erl
@@ -0,0 +1,22 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars5).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case AnAtom of
+ OtherAtom -> register(OtherAtom, Pid);
+ _Other -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars6.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars6.erl
new file mode 100644
index 0000000000..cf22ab1883
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars6.erl
@@ -0,0 +1,22 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars6).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case {AnAtom, Pid} of
+ {OtherAtom, APid} -> register(OtherAtom, APid);
+ _Other -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars7.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars7.erl
new file mode 100644
index 0000000000..4bce53982a
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars7.erl
@@ -0,0 +1,22 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars7).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case [AnAtom, Pid] of
+ [OtherAtom, APid] -> register(OtherAtom, APid);
+ _Other -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars8.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars8.erl
new file mode 100644
index 0000000000..937b83cf02
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars8.erl
@@ -0,0 +1,22 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars8).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case AnAtom =:= OtherAtom of
+ true -> register(OtherAtom, Pid);
+ false -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.
diff --git a/lib/dialyzer/test/race_SUITE_data/src/whereis_vars9.erl b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars9.erl
new file mode 100644
index 0000000000..9beb67ca38
--- /dev/null
+++ b/lib/dialyzer/test/race_SUITE_data/src/whereis_vars9.erl
@@ -0,0 +1,22 @@
+%% This tests that warnings do appear when there is no specific
+%% information about the types and the variables are bound.
+
+-module(whereis_vars9).
+-export([start/2]).
+
+start(AnAtom, Fun) ->
+ case whereis(AnAtom) of
+ undefined ->
+ Pid = spawn(Fun),
+ OtherAtom = kostis,
+ case Pid =:= self() of
+ true -> ok;
+ false ->
+ case AnAtom == OtherAtom of
+ true -> register(OtherAtom, Pid);
+ false -> ok
+ end
+ end;
+ P when is_pid(P) ->
+ ok
+ end.