diff options
author | Stavros Aronis <[email protected]> | 2011-05-03 17:44:59 +0300 |
---|---|---|
committer | Stavros Aronis <[email protected]> | 2011-05-13 09:25:32 +0300 |
commit | 3a7af1c4934c0ce4682d88a6dafc178c1d12a703 (patch) | |
tree | 3b13be97a6303e7f3212666004d481e90b5ea88b /lib/dialyzer/test/small_SUITE_data/src | |
parent | 5703c55ea47c52a8dc8475085a8657422da3535e (diff) | |
download | otp-3a7af1c4934c0ce4682d88a6dafc178c1d12a703.tar.gz otp-3a7af1c4934c0ce4682d88a6dafc178c1d12a703.tar.bz2 otp-3a7af1c4934c0ce4682d88a6dafc178c1d12a703.zip |
Fix server loop detection
Dialyzer does not normally emit warnings for functions that
implement non-terminating server loops. This detection failed
when some of the elements in an SCC terminated normally (being
for example list comprehensions or other generic anonymous
functions that were included in the SCC). This patch fixes that.
Diffstat (limited to 'lib/dialyzer/test/small_SUITE_data/src')
-rw-r--r-- | lib/dialyzer/test/small_SUITE_data/src/no_return_bug.erl | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/dialyzer/test/small_SUITE_data/src/no_return_bug.erl b/lib/dialyzer/test/small_SUITE_data/src/no_return_bug.erl new file mode 100644 index 0000000000..5c24902590 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/no_return_bug.erl @@ -0,0 +1,42 @@ +%% Dialyzer couldn't infer that monitor_diskspace would go in an infinite loop +%% instead of crashing due to the existence of list comprehensions that have a +%% normal success typing. These were added to the monitor_diskspace's SCC and +%% dialyzer_typesig didn't try to assign unit() to monitor_diskspace, as it +%% required all the members of the SCC to return none(). +%% +%% Testcase was submitted in erlang-questions mailing list by Prashanth Mundkur +%% (http://erlang.org/pipermail/erlang-questions/2011-May/058063.html) + +-module(no_return_bug). +-export([diskspace/1, monitor_diskspace/2, refresh_tags/1, monitor_launch/0]). + +-type diskinfo() :: {non_neg_integer(), non_neg_integer()}. + +-spec diskspace(nonempty_string()) -> {'ok', diskinfo()} | {'error', term()}. +diskspace(Path) -> + case Path of + "a" -> {ok, {0,0}}; + _ -> {error, error} + end. + +-spec monitor_diskspace(nonempty_string(), + [{diskinfo(), nonempty_string()}]) -> + no_return(). +monitor_diskspace(Root, Vols) -> + Df = fun(VolName) -> + diskspace(filename:join([Root, VolName])) + end, + NewVols = [{Space, VolName} + || {VolName, {ok, Space}} + <- [{VolName, Df(VolName)} + || {_OldSpace, VolName} <- Vols]], + monitor_diskspace(Root, NewVols). + +-spec refresh_tags(nonempty_string()) -> no_return(). +refresh_tags(Root) -> + {ok, _} = diskspace(Root), + refresh_tags(Root). + +monitor_launch() -> + spawn_link(fun() -> refresh_tags("abc") end), + spawn_link(fun() -> monitor_diskspace("root", [{{0,0}, "a"}]) end). |