aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dialyzer/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dialyzer/test')
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args2
-rw-r--r--lib/dialyzer/test/behaviour_SUITE_data/src/proper/proper_typeserver.erl10
-rw-r--r--lib/dialyzer/test/dialyzer_common.erl10
-rw-r--r--lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_typeserver.erl10
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/results/compiler2
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_validator.erl2
-rw-r--r--lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl6
-rw-r--r--lib/dialyzer/test/overspecs_SUITE_data/dialyzer_options1
-rw-r--r--lib/dialyzer/test/overspecs_SUITE_data/results/iodata2
-rw-r--r--lib/dialyzer/test/overspecs_SUITE_data/results/iolist2
-rw-r--r--lib/dialyzer/test/overspecs_SUITE_data/src/iodata.erl41
-rw-r--r--lib/dialyzer/test/overspecs_SUITE_data/src/iolist.erl41
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl2
-rw-r--r--lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/chars6
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/extra_range4
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/fun_arity32
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/maps_sum2
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/stacktrace5
-rw-r--r--lib/dialyzer/test/small_SUITE_data/results/unused_funs5
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/chars.erl18
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/extra_range.erl59
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/stacktrace.erl73
-rw-r--r--lib/dialyzer/test/small_SUITE_data/src/unused_funs.erl21
-rw-r--r--lib/dialyzer/test/specdiffs_SUITE_data/dialyzer_options1
-rw-r--r--lib/dialyzer/test/specdiffs_SUITE_data/results/iodata3
-rw-r--r--lib/dialyzer/test/specdiffs_SUITE_data/results/iolist2
-rw-r--r--lib/dialyzer/test/specdiffs_SUITE_data/src/iodata.erl41
-rw-r--r--lib/dialyzer/test/specdiffs_SUITE_data/src/iolist.erl41
29 files changed, 398 insertions, 48 deletions
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args
index 1eb8cd455b..1be0ce0d8c 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args
+++ b/lib/dialyzer/test/behaviour_SUITE_data/results/gen_server_incorrect_args
@@ -1,5 +1,5 @@
gen_server_incorrect_args.erl:3: Undefined callback function handle_cast/2 (behaviour gen_server)
gen_server_incorrect_args.erl:3: Undefined callback function init/1 (behaviour gen_server)
-gen_server_incorrect_args.erl:7: The inferred return type of handle_call/3 ({'no'} | {'ok'}) has nothing in common with {'noreply',_} | {'noreply',_,'hibernate' | 'infinity' | non_neg_integer()} | {'reply',_,_} | {'stop',_,_} | {'reply',_,_,'hibernate' | 'infinity' | non_neg_integer()} | {'stop',_,_,_}, which is the expected return type for the callback of the gen_server behaviour
+gen_server_incorrect_args.erl:7: The inferred return type of handle_call/3 ({'no'} | {'ok'}) has nothing in common with {'noreply',_} | {'noreply',_,'hibernate' | 'infinity' | non_neg_integer() | {'continue',_}} | {'reply',_,_} | {'stop',_,_} | {'reply',_,_,'hibernate' | 'infinity' | non_neg_integer() | {'continue',_}} | {'stop',_,_,_}, which is the expected return type for the callback of the gen_server behaviour
gen_server_incorrect_args.erl:7: The inferred type for the 2nd argument of handle_call/3 ('boo' | 'foo') is not a supertype of {pid(),_}, which is expected type for this argument in the callback of the gen_server behaviour
diff --git a/lib/dialyzer/test/behaviour_SUITE_data/src/proper/proper_typeserver.erl b/lib/dialyzer/test/behaviour_SUITE_data/src/proper/proper_typeserver.erl
index b16075763f..12f6532c0c 100644
--- a/lib/dialyzer/test/behaviour_SUITE_data/src/proper/proper_typeserver.erl
+++ b/lib/dialyzer/test/behaviour_SUITE_data/src/proper/proper_typeserver.erl
@@ -539,7 +539,7 @@ apply_spec_test({Mod,Fun,_Arity}=MFA, {_Domain,Range}, SpecTimeout, FalsePositiv
try apply(Mod, Fun, Args) of
X -> {ok, X}
catch
- X:Y -> {X, Y}
+ X:Y:S -> {{X, Y}, S}
end,
case Result of
{ok, Z} ->
@@ -551,15 +551,15 @@ apply_spec_test({Mod,Fun,_Arity}=MFA, {_Domain,Range}, SpecTimeout, FalsePositiv
false ->
false
end;
- Exception when is_function(FalsePositiveMFAs) ->
+ {Exception, S2} when is_function(FalsePositiveMFAs) ->
case FalsePositiveMFAs(MFA, Args, Exception) of
true ->
true;
false ->
- error(Exception, erlang:get_stacktrace())
+ error(Exception, S2)
end;
- Exception ->
- error(Exception, erlang:get_stacktrace())
+ {Exception, S3} ->
+ error(Exception, S3)
end
end).
diff --git a/lib/dialyzer/test/dialyzer_common.erl b/lib/dialyzer/test/dialyzer_common.erl
index 48083a2731..1a8403f486 100644
--- a/lib/dialyzer/test/dialyzer_common.erl
+++ b/lib/dialyzer/test/dialyzer_common.erl
@@ -221,13 +221,9 @@ get_suites(Dir) ->
end.
suffix(String, Suffix) ->
- case string:rstr(String, Suffix) of
- 0 -> no;
- Index ->
- case string:substr(String, Index) =:= Suffix of
- true -> {yes, string:sub_string(String,1,Index-1)};
- false -> no
- end
+ case string:split(String, Suffix, trailing) of
+ [Prefix,[]] -> {yes, Prefix};
+ _ -> no
end.
-spec create_suite(string()) -> 'ok'.
diff --git a/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_typeserver.erl b/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_typeserver.erl
index 1677b4efb8..529f9fba72 100644
--- a/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_typeserver.erl
+++ b/lib/dialyzer/test/opaque_SUITE_data/src/proper/proper_typeserver.erl
@@ -533,7 +533,7 @@ apply_spec_test({Mod,Fun,_Arity}=MFA, {_Domain,Range}, SpecTimeout, FalsePositiv
try apply(Mod,Fun,Args) of
X -> {ok, X}
catch
- X:Y -> {X, Y}
+ X:Y:S -> {{X, Y}, S}
end,
case Result of
{ok, Z} ->
@@ -545,15 +545,15 @@ apply_spec_test({Mod,Fun,_Arity}=MFA, {_Domain,Range}, SpecTimeout, FalsePositiv
false ->
false
end;
- Exception when is_function(FalsePositiveMFAs) ->
+ {Exception, S2} when is_function(FalsePositiveMFAs) ->
case FalsePositiveMFAs(MFA, Args, Exception) of
true ->
true;
false ->
- error(Exception, erlang:get_stacktrace())
+ error(Exception, S2)
end;
- Exception ->
- error(Exception, erlang:get_stacktrace())
+ {Exception, S3} ->
+ error(Exception, S3)
end
end).
diff --git a/lib/dialyzer/test/options1_SUITE_data/results/compiler b/lib/dialyzer/test/options1_SUITE_data/results/compiler
index cbb5115c91..e1dc038800 100644
--- a/lib/dialyzer/test/options1_SUITE_data/results/compiler
+++ b/lib/dialyzer/test/options1_SUITE_data/results/compiler
@@ -28,7 +28,7 @@ cerl_inline.erl:2750: The pattern <{[], L, D}, Vs> can never match the type <[1.
cerl_inline.erl:2752: The pattern <{[], _L, D}, Vs> can never match the type <[1..255,...],[any()]>
cerl_inline.erl:2754: The pattern <{F, L, D}, Vs> can never match the type <[1..255,...],[any()]>
cerl_inline.erl:2756: The pattern <{F, _L, D}, Vs> can never match the type <[1..255,...],[any()]>
-compile.erl:788: The pattern {'error', Es} can never match the type {'ok',<<_:64,_:_*8>>}
+compile.erl:792: The pattern {'error', Es} can never match the type {'ok',<<_:64,_:_*8>>}
core_lint.erl:473: The pattern <{'c_atom', _, 'all'}, 'binary', _Def, St> can never match the type <_,#c_nil{} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple',_,_} | #c_cons{hd::#c_nil{} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple',_,_} | #c_cons{hd::{_,_} | {_,_,_} | {_,_,_,_},tl::{_,_} | {_,_,_} | {_,_,_,_}},tl::#c_nil{} | {'c_atom' | 'c_char' | 'c_float' | 'c_int' | 'c_string' | 'c_tuple',_,_} | #c_cons{hd::{_,_} | {_,_,_} | {_,_,_,_},tl::{_,_} | {_,_,_} | {_,_,_,_}}},[any()],_>
core_lint.erl:505: The pattern <_Req, 'unknown', St> can never match the type <non_neg_integer(),non_neg_integer(),_>
sys_pre_expand.erl:625: Call to missing or unexported function erlang:hash/2
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_validator.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_validator.erl
index 8fe43163f6..ea92613781 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_validator.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/beam_validator.erl
@@ -174,7 +174,7 @@ validate_error(Error, Name, Ar) ->
-endif.
validate_error_1(Error, Name, Ar) ->
{{'_',Name,Ar},
- {internal_error,'_',{Error,erlang:get_stacktrace()}}}.
+ {internal_error,'_',{Error,[]}}}.
-record(st, %Emulation state
{x=init_regs(0, term), %x register info.
diff --git a/lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl b/lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl
index 7e5ccde2fd..6838cf6734 100644
--- a/lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl
+++ b/lib/dialyzer/test/options1_SUITE_data/src/compiler/compile.erl
@@ -228,11 +228,15 @@ os_process_size() ->
case os:type() of
{unix, sunos} ->
Size = os:cmd("ps -o vsz -p " ++ os:getpid() ++ " | tail -1"),
- list_to_integer(lib:nonl(Size));
+ list_to_integer(nonl(Size));
_ ->
0
end.
+nonl([$\n]) -> [];
+nonl([]) -> [];
+nonl([H|T]) -> [H|nonl(T)].
+
run_tc({Name,Fun}, St) ->
Before0 = statistics(runtime),
Val = (catch Fun(St)),
diff --git a/lib/dialyzer/test/overspecs_SUITE_data/dialyzer_options b/lib/dialyzer/test/overspecs_SUITE_data/dialyzer_options
new file mode 100644
index 0000000000..ff4517e59d
--- /dev/null
+++ b/lib/dialyzer/test/overspecs_SUITE_data/dialyzer_options
@@ -0,0 +1 @@
+{dialyzer_options, [{warnings, [overspecs]}]}.
diff --git a/lib/dialyzer/test/overspecs_SUITE_data/results/iodata b/lib/dialyzer/test/overspecs_SUITE_data/results/iodata
new file mode 100644
index 0000000000..d9c70330ec
--- /dev/null
+++ b/lib/dialyzer/test/overspecs_SUITE_data/results/iodata
@@ -0,0 +1,2 @@
+
+iodata.erl:7: The success typing for iodata:encode/2 implies that the function might also return integer() but the specification return is binary() | maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | [])
diff --git a/lib/dialyzer/test/overspecs_SUITE_data/results/iolist b/lib/dialyzer/test/overspecs_SUITE_data/results/iolist
new file mode 100644
index 0000000000..ca556f017c
--- /dev/null
+++ b/lib/dialyzer/test/overspecs_SUITE_data/results/iolist
@@ -0,0 +1,2 @@
+
+iolist.erl:7: The success typing for iolist:encode/2 implies that the function might also return integer() but the specification return is maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | [])
diff --git a/lib/dialyzer/test/overspecs_SUITE_data/src/iodata.erl b/lib/dialyzer/test/overspecs_SUITE_data/src/iodata.erl
new file mode 100644
index 0000000000..caa44f6c91
--- /dev/null
+++ b/lib/dialyzer/test/overspecs_SUITE_data/src/iodata.erl
@@ -0,0 +1,41 @@
+-module(iodata).
+
+%% A small part of beam_asm.
+
+-export([encode/2]).
+
+-spec encode(non_neg_integer(), integer()) -> iodata(). % extra range binary()
+
+encode(Tag, N) when Tag >= 0, N < 0 ->
+ encode1(Tag, negative_to_bytes(N));
+encode(Tag, N) when Tag >= 0, N < 16 ->
+ (N bsl 4) bor Tag; % not in the specification
+encode(Tag, N) when Tag >= 0, N < 16#800 ->
+ [((N bsr 3) band 2#11100000) bor Tag bor 2#00001000, N band 16#ff];
+encode(Tag, N) when Tag >= 0 ->
+ encode1(Tag, to_bytes(N)).
+
+encode1(Tag, Bytes) ->
+ case iolist_size(Bytes) of
+ Num when 2 =< Num, Num =< 8 ->
+ [((Num-2) bsl 5) bor 2#00011000 bor Tag| Bytes];
+ Num when 8 < Num ->
+ [2#11111000 bor Tag, encode(0, Num-9)| Bytes]
+ end.
+
+to_bytes(N) ->
+ Bin = binary:encode_unsigned(N),
+ case Bin of
+ <<0:1,_/bits>> -> Bin;
+ <<1:1,_/bits>> -> [0,Bin]
+ end.
+
+negative_to_bytes(N) when N >= -16#8000 ->
+ <<N:16>>;
+negative_to_bytes(N) ->
+ Bytes = byte_size(binary:encode_unsigned(-N)),
+ Bin = <<N:Bytes/unit:8>>,
+ case Bin of
+ <<0:1,_/bits>> -> [16#ff,Bin];
+ <<1:1,_/bits>> -> Bin
+ end.
diff --git a/lib/dialyzer/test/overspecs_SUITE_data/src/iolist.erl b/lib/dialyzer/test/overspecs_SUITE_data/src/iolist.erl
new file mode 100644
index 0000000000..7cceeda24e
--- /dev/null
+++ b/lib/dialyzer/test/overspecs_SUITE_data/src/iolist.erl
@@ -0,0 +1,41 @@
+-module(iolist).
+
+%% A small part of beam_asm.
+
+-export([encode/2]).
+
+-spec encode(non_neg_integer(), integer()) -> iolist().
+
+encode(Tag, N) when Tag >= 0, N < 0 ->
+ encode1(Tag, negative_to_bytes(N));
+encode(Tag, N) when Tag >= 0, N < 16 ->
+ (N bsl 4) bor Tag; % not in the specification
+encode(Tag, N) when Tag >= 0, N < 16#800 ->
+ [((N bsr 3) band 2#11100000) bor Tag bor 2#00001000, N band 16#ff];
+encode(Tag, N) when Tag >= 0 ->
+ encode1(Tag, to_bytes(N)).
+
+encode1(Tag, Bytes) ->
+ case iolist_size(Bytes) of
+ Num when 2 =< Num, Num =< 8 ->
+ [((Num-2) bsl 5) bor 2#00011000 bor Tag| Bytes];
+ Num when 8 < Num ->
+ [2#11111000 bor Tag, encode(0, Num-9)| Bytes]
+ end.
+
+to_bytes(N) ->
+ Bin = binary:encode_unsigned(N),
+ case Bin of
+ <<0:1,_/bits>> -> Bin;
+ <<1:1,_/bits>> -> [0,Bin]
+ end.
+
+negative_to_bytes(N) when N >= -16#8000 ->
+ <<N:16>>;
+negative_to_bytes(N) ->
+ Bytes = byte_size(binary:encode_unsigned(-N)),
+ Bin = <<N:Bytes/unit:8>>,
+ case Bin of
+ <<0:1,_/bits>> -> [16#ff,Bin];
+ <<1:1,_/bits>> -> Bin
+ end.
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl
index a48f73274b..52db2d9096 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/inets/mod_esi.erl
@@ -285,7 +285,7 @@ eval(Info,"GET",CGIBody,Modules) ->
"~n Modules: ~p",[Modules]),
case auth(CGIBody,Modules) of
true ->
- case lib:eval_str(string:concat(CGIBody,". ")) of
+ case erl_eval:eval_str(string:concat(CGIBody,". ")) of
{error,Reason} ->
?vlog("eval -> error:"
"~n Reason: ~p",[Reason]),
diff --git a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl
index 09e310530d..af49ceff72 100644
--- a/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl
+++ b/lib/dialyzer/test/r9c_SUITE_data/src/mnesia/mnesia_tm.erl
@@ -2051,7 +2051,7 @@ display_pid_info(Pid) ->
Other
end,
Reds = fetch(reductions, Info),
- LM = length(fetch(messages, Info)),
+ LM = fetch(message_queue_len, Info),
pformat(io_lib:format("~p", [Pid]),
io_lib:format("~p", [Call]),
io_lib:format("~p", [Curr]), Reds, LM)
diff --git a/lib/dialyzer/test/small_SUITE_data/results/chars b/lib/dialyzer/test/small_SUITE_data/results/chars
index 2c1f8f8d17..72fbdb4528 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/chars
+++ b/lib/dialyzer/test/small_SUITE_data/results/chars
@@ -1,4 +1,4 @@
-chars.erl:29: Invalid type specification for function chars:f/1. The success typing is (#{'b':=50}) -> 'ok'
-chars.erl:32: Function t1/0 has no local return
-chars.erl:32: The call chars:f(#{'b':=50}) breaks the contract (#{'a':=49,'b'=>50,'c'=>51}) -> 'ok'
+chars.erl:37: Invalid type specification for function chars:f/1. The success typing is (#{'b':=50}) -> 'ok'
+chars.erl:40: Function t1/0 has no local return
+chars.erl:40: The call chars:f(#{'b':=50}) breaks the contract (#{'a':=49,'b'=>50,'c'=>51}) -> 'ok'
diff --git a/lib/dialyzer/test/small_SUITE_data/results/extra_range b/lib/dialyzer/test/small_SUITE_data/results/extra_range
new file mode 100644
index 0000000000..ec50c95c4e
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/extra_range
@@ -0,0 +1,4 @@
+
+extra_range.erl:29: The pattern 'ok' can never match the type 'error'
+extra_range.erl:43: The pattern 'no' can never match the type 'maybe' | 'yes'
+extra_range.erl:58: The pattern 'maybe' can never match the type 'no' | 'yes'
diff --git a/lib/dialyzer/test/small_SUITE_data/results/fun_arity b/lib/dialyzer/test/small_SUITE_data/results/fun_arity
index e916b2483f..8b7a538758 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/fun_arity
+++ b/lib/dialyzer/test/small_SUITE_data/results/fun_arity
@@ -1,37 +1,37 @@
-fun_arity.erl:100: Fun application will fail since _@c1 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:100: Fun application will fail since _1 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:100: Function 'Mfa_0_ko'/1 has no local return
-fun_arity.erl:104: Fun application will fail since _@c1 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:104: Fun application will fail since _1 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:104: Function 'Mfa_1_ko'/1 has no local return
-fun_arity.erl:111: Fun application will fail since _@c1 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:111: Fun application will fail since _1 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:111: Function mFa_0_ko/1 has no local return
-fun_arity.erl:115: Fun application will fail since _@c1 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:115: Fun application will fail since _1 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:115: Function mFa_1_ko/1 has no local return
-fun_arity.erl:122: Fun application will fail since _@c2 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:122: Fun application will fail since _2 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:122: Function 'MFa_0_ko'/2 has no local return
-fun_arity.erl:126: Fun application will fail since _@c2 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:126: Fun application will fail since _2 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:126: Function 'MFa_1_ko'/2 has no local return
-fun_arity.erl:35: Fun application will fail since _@c0 :: fun(() -> 'ok') is not a function of arity 1
+fun_arity.erl:35: Fun application will fail since _0 :: fun(() -> 'ok') is not a function of arity 1
fun_arity.erl:35: Function f_0_ko/0 has no local return
-fun_arity.erl:39: Fun application will fail since _@c0 :: fun((_) -> 'ok') is not a function of arity 0
+fun_arity.erl:39: Fun application will fail since _0 :: fun((_) -> 'ok') is not a function of arity 0
fun_arity.erl:39: Function f_1_ko/0 has no local return
-fun_arity.erl:48: Fun application will fail since _@c0 :: fun(() -> 'ok') is not a function of arity 1
+fun_arity.erl:48: Fun application will fail since _0 :: fun(() -> 'ok') is not a function of arity 1
fun_arity.erl:48: Function fa_0_ko/0 has no local return
-fun_arity.erl:53: Fun application will fail since _@c0 :: fun((_) -> 'ok') is not a function of arity 0
+fun_arity.erl:53: Fun application will fail since _0 :: fun((_) -> 'ok') is not a function of arity 0
fun_arity.erl:53: Function fa_1_ko/0 has no local return
-fun_arity.erl:63: Fun application will fail since _@c0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:63: Fun application will fail since _0 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:63: Function mfa_0_ko/0 has no local return
-fun_arity.erl:68: Fun application will fail since _@c0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:68: Fun application will fail since _0 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:68: Function mfa_1_ko/0 has no local return
-fun_arity.erl:76: Fun application will fail since _@c0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:76: Fun application will fail since _0 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:76: Function mfa_ne_0_ko/0 has no local return
fun_arity.erl:78: Function mf_ne/0 will never be called
-fun_arity.erl:81: Fun application will fail since _@c0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:81: Fun application will fail since _0 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:81: Function mfa_ne_1_ko/0 has no local return
fun_arity.erl:83: Function mf_ne/1 will never be called
-fun_arity.erl:89: Fun application will fail since _@c0 :: fun(() -> any()) is not a function of arity 1
+fun_arity.erl:89: Fun application will fail since _0 :: fun(() -> any()) is not a function of arity 1
fun_arity.erl:89: Function mfa_nd_0_ko/0 has no local return
fun_arity.erl:90: Call to missing or unexported function fun_arity:mf_nd/0
-fun_arity.erl:93: Fun application will fail since _@c0 :: fun((_) -> any()) is not a function of arity 0
+fun_arity.erl:93: Fun application will fail since _0 :: fun((_) -> any()) is not a function of arity 0
fun_arity.erl:93: Function mfa_nd_1_ko/0 has no local return
fun_arity.erl:94: Call to missing or unexported function fun_arity:mf_nd/1
diff --git a/lib/dialyzer/test/small_SUITE_data/results/maps_sum b/lib/dialyzer/test/small_SUITE_data/results/maps_sum
index bd192bdb93..b29ac77d88 100644
--- a/lib/dialyzer/test/small_SUITE_data/results/maps_sum
+++ b/lib/dialyzer/test/small_SUITE_data/results/maps_sum
@@ -1,4 +1,4 @@
-maps_sum.erl:15: Invalid type specification for function maps_sum:wrong1/1. The success typing is (map()) -> any()
+maps_sum.erl:15: Invalid type specification for function maps_sum:wrong1/1. The success typing is (maps:iterator() | map()) -> any()
maps_sum.erl:26: Function wrong2/1 has no local return
maps_sum.erl:27: The call lists:foldl(fun((_,_,_) -> any()),0,Data::any()) will never return since it differs in the 1st argument from the success typing arguments: (fun((_,_) -> any()),any(),[any()])
diff --git a/lib/dialyzer/test/small_SUITE_data/results/stacktrace b/lib/dialyzer/test/small_SUITE_data/results/stacktrace
new file mode 100644
index 0000000000..fd60881953
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/stacktrace
@@ -0,0 +1,5 @@
+
+stacktrace.erl:11: The pattern {'a', 'b'} can never match the type [{atom(),atom(),[any()] | byte(),[{'file',string()} | {'line',pos_integer()}]}]
+stacktrace.erl:19: The pattern ['a', 'b'] can never match the type [{atom(),atom(),[any()] | byte(),[{'file',string()} | {'line',pos_integer()}]}]
+stacktrace.erl:44: The pattern {'a', 'b'} can never match the type [{atom(),atom(),[any()] | byte(),[{'file',string()} | {'line',pos_integer()}]}]
+stacktrace.erl:53: The pattern ['a', 'b'] can never match the type [{atom(),atom(),[any()] | byte(),[{'file',string()} | {'line',pos_integer()}]}]
diff --git a/lib/dialyzer/test/small_SUITE_data/results/unused_funs b/lib/dialyzer/test/small_SUITE_data/results/unused_funs
new file mode 100644
index 0000000000..c468457ead
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/results/unused_funs
@@ -0,0 +1,5 @@
+
+unused_funs.erl:10: The pattern 'error' can never match the type 'other_error'
+unused_funs.erl:15: Function not_used/0 will never be called
+unused_funs.erl:19: Function foo/1 will never be called
+unused_funs.erl:7: Function test/0 has no local return
diff --git a/lib/dialyzer/test/small_SUITE_data/src/chars.erl b/lib/dialyzer/test/small_SUITE_data/src/chars.erl
index 1e9c8ab6b9..62b90cf54d 100644
--- a/lib/dialyzer/test/small_SUITE_data/src/chars.erl
+++ b/lib/dialyzer/test/small_SUITE_data/src/chars.erl
@@ -12,17 +12,25 @@
-spec t() -> $0-$0..$9-$0| $?.
t() ->
- c(#r{f = $z - 3}),
+ r(#r{f = $z - 3}),
+ r(#r{f = 97}),
+ c($/),
c($z - 3),
c($B).
-spec c(cs()) -> $3-$0..$9-$0.
-
-c($A + 1) -> 2;
+c($A + 1) -> $9-$0;
c(C) ->
case C of
- $z - 3 -> 3;
- #r{f = $z - 3} -> 7
+ $z - 3 -> $3-$0;
+ _ -> $7-$0
+ end.
+
+-spec r(#r{f :: $a..$z}) -> ok | error.
+r(R) ->
+ case R of
+ #r{f = $z - 3} -> error;
+ _ -> ok
end.
%% Display contract with character in warning:
diff --git a/lib/dialyzer/test/small_SUITE_data/src/extra_range.erl b/lib/dialyzer/test/small_SUITE_data/src/extra_range.erl
new file mode 100644
index 0000000000..9d6ba89c95
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/extra_range.erl
@@ -0,0 +1,59 @@
+%% Test that a spec containing more items than actually returned
+%% (whether by accident or by benign overspeccing) does not prevent
+%% detection of impossible matches.
+
+-module(extra_range).
+
+-export([t1/2, t2/2, t3/2, t4/2]).
+
+-dialyzer([no_return]).
+
+%% this spec matches the behaviour of the code
+-spec normal(integer()) -> ok | error.
+normal(1) -> ok;
+normal(2) -> error.
+
+t1(X, Y) when is_integer(X), is_integer(Y) ->
+ ok = normal(X),
+ error = normal(Y),
+ ok.
+
+
+%% this spec has a typo, which should cause anyone trying to match on
+%% `ok = typo(X)' to get a warning, because `ok' is not in the spec
+-spec typo(integer()) -> ook | error.
+typo(1) -> ok;
+typo(2) -> error.
+
+t2(X, Y) when is_integer(X), is_integer(Y) ->
+ ok = typo(X), % warning expected - not allowed according to spec
+ error = typo(Y),
+ ok.
+
+
+%% this is overspecified, and should cause a warning for trying
+%% to match on `no = over(X)', because it cannot succeed and either
+%% the spec should be updated or the code should be extended
+-spec over(integer()) -> yes | no | maybe.
+over(1) -> yes;
+over(_) -> maybe.
+
+t3(X, Y) when is_integer(X), is_integer(Y) ->
+ yes = over(X),
+ no = over(Y), % warning expected - spec or code needs fixing
+ maybe = over(X + Y),
+ ok.
+
+
+%% this is underspecified, which should cause anyone trying to match on
+%% `maybe = under(X)' to get a warning, because `maybe' is not in the spec
+-spec under(integer()) -> yes | no.
+under(1) -> yes;
+under(2) -> no;
+under(_) -> maybe.
+
+t4(X, Y) when is_integer(X), is_integer(Y) ->
+ yes = under(X),
+ no = under(Y),
+ maybe = under(X + Y), % warning expected - not in spec
+ ok.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/stacktrace.erl b/lib/dialyzer/test/small_SUITE_data/src/stacktrace.erl
new file mode 100644
index 0000000000..de79e710e9
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/stacktrace.erl
@@ -0,0 +1,73 @@
+-module(stacktrace).
+
+%% Check the stacktrace variable introduced in Erlang/OTP 21.0
+
+-export([t1/0, t2/0, t3/0, t4/0, s1/0, s2/0, s3/0, s4/0]).
+
+t1() ->
+ try foo:bar()
+ catch
+ E:P:S ->
+ {a,b} = S, % can never match
+ {E, P}
+ end.
+
+t2() ->
+ try foo:bar()
+ catch
+ E:P:S ->
+ [a,b] = S, % can never match
+ {E, P}
+ end.
+
+t3() ->
+ try foo:bar()
+ catch
+ E:P:S ->
+ [{m,f,[],[]}] = S,
+ {E, P}
+ end.
+
+t4() ->
+ try foo:bar()
+ catch
+ E:P:S ->
+ [{m,f,1,[{file,"tjo"},{line,95}]}] = S,
+ {E, P}
+ end.
+
+s1() ->
+ try foo:bar()
+ catch
+ E:P ->
+ S = erlang:get_stacktrace(),
+ {a,b} = S, % can never match
+ {E, P}
+ end.
+
+s2() ->
+ try foo:bar()
+ catch
+ E:P ->
+ S = erlang:get_stacktrace(),
+ [a,b] = S, % can never match
+ {E, P}
+ end.
+
+s3() ->
+ try foo:bar()
+ catch
+ E:P ->
+ S = erlang:get_stacktrace(),
+ [{m,f,[],[]}] = S,
+ {E, P}
+ end.
+
+s4() ->
+ try foo:bar()
+ catch
+ E:P ->
+ S = erlang:get_stacktrace(),
+ [{m,f,1,[{file,"tjo"},{line,95}]}] = S,
+ {E, P}
+ end.
diff --git a/lib/dialyzer/test/small_SUITE_data/src/unused_funs.erl b/lib/dialyzer/test/small_SUITE_data/src/unused_funs.erl
new file mode 100644
index 0000000000..c24cf3ea81
--- /dev/null
+++ b/lib/dialyzer/test/small_SUITE_data/src/unused_funs.erl
@@ -0,0 +1,21 @@
+%% See also ERL-593.
+
+-module(unused_funs).
+
+-export([test/0]).
+
+test() -> % "has no local return"
+ Var = outer_scope,
+ case other_error of
+ error -> % "can never match"
+ %% No warnings "no local return" and "_ = 1 can never match 0" (!)
+ foo(fun() -> {Var, 1 = 0} end)
+ end.
+
+not_used() -> % "will never be called"
+ %% No warnings "no local return" and "1 can never match 0".
+ foo(fun() -> 1 = 0 end).
+
+foo(Fun) -> % "will never be called"
+ 1 = 0, % No pattern match warning (foo/1 is not traversed at all).
+ Fun().
diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/dialyzer_options b/lib/dialyzer/test/specdiffs_SUITE_data/dialyzer_options
new file mode 100644
index 0000000000..56b36f2ed4
--- /dev/null
+++ b/lib/dialyzer/test/specdiffs_SUITE_data/dialyzer_options
@@ -0,0 +1 @@
+{dialyzer_options, [{warnings, [specdiffs]}]}.
diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/results/iodata b/lib/dialyzer/test/specdiffs_SUITE_data/results/iodata
new file mode 100644
index 0000000000..3fb12fe000
--- /dev/null
+++ b/lib/dialyzer/test/specdiffs_SUITE_data/results/iodata
@@ -0,0 +1,3 @@
+
+iodata.erl:7: The specification for iodata:encode/2 states that the function might also return binary() but the inferred return is nonempty_maybe_improper_list(<<_:8,_:_*8>> | nonempty_maybe_improper_list(<<_:8,_:_*8>> | nonempty_maybe_improper_list(any(),<<_:8,_:_*8>> | []) | byte(),<<_:8,_:_*8>> | []) | integer(),<<_:8,_:_*8>> | []) | integer()
+iodata.erl:7: The success typing for iodata:encode/2 implies that the function might also return integer() but the specification return is binary() | maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | [])
diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/results/iolist b/lib/dialyzer/test/specdiffs_SUITE_data/results/iolist
new file mode 100644
index 0000000000..ca556f017c
--- /dev/null
+++ b/lib/dialyzer/test/specdiffs_SUITE_data/results/iolist
@@ -0,0 +1,2 @@
+
+iolist.erl:7: The success typing for iolist:encode/2 implies that the function might also return integer() but the specification return is maybe_improper_list(binary() | maybe_improper_list(any(),binary() | []) | byte(),binary() | [])
diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/src/iodata.erl b/lib/dialyzer/test/specdiffs_SUITE_data/src/iodata.erl
new file mode 100644
index 0000000000..caa44f6c91
--- /dev/null
+++ b/lib/dialyzer/test/specdiffs_SUITE_data/src/iodata.erl
@@ -0,0 +1,41 @@
+-module(iodata).
+
+%% A small part of beam_asm.
+
+-export([encode/2]).
+
+-spec encode(non_neg_integer(), integer()) -> iodata(). % extra range binary()
+
+encode(Tag, N) when Tag >= 0, N < 0 ->
+ encode1(Tag, negative_to_bytes(N));
+encode(Tag, N) when Tag >= 0, N < 16 ->
+ (N bsl 4) bor Tag; % not in the specification
+encode(Tag, N) when Tag >= 0, N < 16#800 ->
+ [((N bsr 3) band 2#11100000) bor Tag bor 2#00001000, N band 16#ff];
+encode(Tag, N) when Tag >= 0 ->
+ encode1(Tag, to_bytes(N)).
+
+encode1(Tag, Bytes) ->
+ case iolist_size(Bytes) of
+ Num when 2 =< Num, Num =< 8 ->
+ [((Num-2) bsl 5) bor 2#00011000 bor Tag| Bytes];
+ Num when 8 < Num ->
+ [2#11111000 bor Tag, encode(0, Num-9)| Bytes]
+ end.
+
+to_bytes(N) ->
+ Bin = binary:encode_unsigned(N),
+ case Bin of
+ <<0:1,_/bits>> -> Bin;
+ <<1:1,_/bits>> -> [0,Bin]
+ end.
+
+negative_to_bytes(N) when N >= -16#8000 ->
+ <<N:16>>;
+negative_to_bytes(N) ->
+ Bytes = byte_size(binary:encode_unsigned(-N)),
+ Bin = <<N:Bytes/unit:8>>,
+ case Bin of
+ <<0:1,_/bits>> -> [16#ff,Bin];
+ <<1:1,_/bits>> -> Bin
+ end.
diff --git a/lib/dialyzer/test/specdiffs_SUITE_data/src/iolist.erl b/lib/dialyzer/test/specdiffs_SUITE_data/src/iolist.erl
new file mode 100644
index 0000000000..7cceeda24e
--- /dev/null
+++ b/lib/dialyzer/test/specdiffs_SUITE_data/src/iolist.erl
@@ -0,0 +1,41 @@
+-module(iolist).
+
+%% A small part of beam_asm.
+
+-export([encode/2]).
+
+-spec encode(non_neg_integer(), integer()) -> iolist().
+
+encode(Tag, N) when Tag >= 0, N < 0 ->
+ encode1(Tag, negative_to_bytes(N));
+encode(Tag, N) when Tag >= 0, N < 16 ->
+ (N bsl 4) bor Tag; % not in the specification
+encode(Tag, N) when Tag >= 0, N < 16#800 ->
+ [((N bsr 3) band 2#11100000) bor Tag bor 2#00001000, N band 16#ff];
+encode(Tag, N) when Tag >= 0 ->
+ encode1(Tag, to_bytes(N)).
+
+encode1(Tag, Bytes) ->
+ case iolist_size(Bytes) of
+ Num when 2 =< Num, Num =< 8 ->
+ [((Num-2) bsl 5) bor 2#00011000 bor Tag| Bytes];
+ Num when 8 < Num ->
+ [2#11111000 bor Tag, encode(0, Num-9)| Bytes]
+ end.
+
+to_bytes(N) ->
+ Bin = binary:encode_unsigned(N),
+ case Bin of
+ <<0:1,_/bits>> -> Bin;
+ <<1:1,_/bits>> -> [0,Bin]
+ end.
+
+negative_to_bytes(N) when N >= -16#8000 ->
+ <<N:16>>;
+negative_to_bytes(N) ->
+ Bytes = byte_size(binary:encode_unsigned(-N)),
+ Bin = <<N:Bytes/unit:8>>,
+ case Bin of
+ <<0:1,_/bits>> -> [16#ff,Bin];
+ <<1:1,_/bits>> -> Bin
+ end.