diff options
Diffstat (limited to 'lib/dialyzer/test/race_SUITE_data/src')
130 files changed, 2939 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/ets_insert_public.erl b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_public.erl new file mode 100644 index 0000000000..4caa9fe8a0 --- /dev/null +++ b/lib/dialyzer/test/race_SUITE_data/src/ets_insert_public.erl @@ -0,0 +1,23 @@ +%% This tests the presence of possible races due to an ets:lookup/ets:insert +%% combination. It takes into account any public ETS tables that might exist. + +-module(ets_insert_public). + +-export([main/1]). + +%% Main +main(Foo) -> + make_table(Foo), + ets:insert(Foo, {counter, 0}), + [{_, N}] = ets:lookup(Foo, counter), + NewN = N + 1, + ets:insert(Foo, {counter, NewN}), + NewN. + +make_table(Foo) -> + init(Foo). + +init(Foo) -> + ets:new(Foo, [named_table, public]), + ets:insert(Foo, {counter, 0}), + {ok, feeling_good}. 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. |