aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Bolinder <hasse@erlang.org>2014-03-06 13:36:46 +0100
committerHans Bolinder <hasse@erlang.org>2014-03-07 08:49:10 +0100
commit3b07ab83d1c64f3aa6ef351c99ec59d1fdd23b59 (patch)
treebef3723afa780b3266373caa88e8956c08fbca31
parent544fb141916d8676bc763318074e4d0783414af1 (diff)
downloadotp-3b07ab83d1c64f3aa6ef351c99ec59d1fdd23b59.tar.gz
otp-3b07ab83d1c64f3aa6ef351c99ec59d1fdd23b59.tar.bz2
otp-3b07ab83d1c64f3aa6ef351c99ec59d1fdd23b59.zip
stdlib: Emit linter warnings for redefined built-in types
Since Erlang/OTP R16B the linter has not emitted warnings when built-in types were re-defined. This bug has been fixed. Thanks to Roberto Aloi for reporting the bug.
-rw-r--r--lib/stdlib/src/erl_lint.erl69
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl44
2 files changed, 78 insertions, 35 deletions
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 1118ff9210..10337b279e 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -2535,32 +2535,39 @@ type_def(Attr, Line, TypeName, ProtoType, Args, St0) ->
CheckType = {type, -1, product, [ProtoType|Args]},
check_type(CheckType, St#lint{types=NewDefs})
end,
- case (dict:is_key(TypePair, TypeDefs) orelse is_var_arity_type(TypeName)) of
- true ->
- case is_default_type(TypePair) of
- true ->
- case is_newly_introduced_builtin_type(TypePair) of
- %% allow some types just for bootstrapping
- true ->
- Warn = {new_builtin_type, TypePair},
- St1 = add_warning(Line, Warn, St0),
+ case is_default_type(TypePair) of
+ true ->
+ case is_obsolete_builtin_type(TypePair) of
+ true -> StoreType(St0);
+ false ->
+ case is_newly_introduced_builtin_type(TypePair) of
+ %% allow some types just for bootstrapping
+ true ->
+ Warn = {new_builtin_type, TypePair},
+ St1 = add_warning(Line, Warn, St0),
StoreType(St1);
- false ->
- add_error(Line, {builtin_type, TypePair}, St0)
- end;
- false -> add_error(Line, {redefine_type, TypePair}, St0)
- end;
- false ->
- St1 = case
- Attr =:= opaque andalso
- is_underspecified(ProtoType, Arity)
- of
- true ->
- Warn = {underspecified_opaque, TypePair},
- add_warning(Line, Warn, St0);
- false -> St0
- end,
- StoreType(St1)
+ false ->
+ add_error(Line, {builtin_type, TypePair}, St0)
+ end
+ end;
+ false ->
+ case
+ dict:is_key(TypePair, TypeDefs)
+ orelse is_var_arity_type(TypeName)
+ of
+ true -> add_error(Line, {redefine_type, TypePair}, St0);
+ false ->
+ St1 = case
+ Attr =:= opaque andalso
+ is_underspecified(ProtoType, Arity)
+ of
+ true ->
+ Warn = {underspecified_opaque, TypePair},
+ add_warning(Line, Warn, St0);
+ false -> St0
+ end,
+ StoreType(St1)
+ end
end.
is_underspecified({type,_,term,[]}, 0) -> true;
@@ -2785,19 +2792,15 @@ is_default_type(_) -> false.
%% R13
is_newly_introduced_builtin_type({arity, 0}) -> true;
-is_newly_introduced_builtin_type({array, 0}) -> true; % opaque
is_newly_introduced_builtin_type({bitstring, 0}) -> true;
-is_newly_introduced_builtin_type({dict, 0}) -> true; % opaque
-is_newly_introduced_builtin_type({digraph, 0}) -> true; % opaque
-is_newly_introduced_builtin_type({gb_set, 0}) -> true; % opaque
-is_newly_introduced_builtin_type({gb_tree, 0}) -> true; % opaque
is_newly_introduced_builtin_type({iodata, 0}) -> true;
-is_newly_introduced_builtin_type({queue, 0}) -> true; % opaque
-is_newly_introduced_builtin_type({set, 0}) -> true; % opaque
%% R13B01
is_newly_introduced_builtin_type({boolean, 0}) -> true;
is_newly_introduced_builtin_type({Name, _}) when is_atom(Name) -> false.
+is_obsolete_builtin_type(TypePair) ->
+ obsolete_builtin_type(TypePair) =/= no.
+
%% Obsolete in OTP 17.0.
obsolete_builtin_type({array, 0}) ->
{deprecated, {array, array, 1}, "OTP 18.0"};
@@ -2815,7 +2818,7 @@ obsolete_builtin_type({set, 0}) ->
{deprecated, {sets, set, 1}, "OTP 18.0"};
obsolete_builtin_type({tid, 0}) ->
{deprecated, {ets, tid}, "OTP 18.0"};
-obsolete_builtin_type({Name, _}) when is_atom(Name) -> no.
+obsolete_builtin_type({Name, A}) when is_atom(Name), is_integer(A) -> no.
%% spec_decl(Line, Fun, Types, State) -> State.
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index 67110f0ae2..00a92ff4bd 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -52,6 +52,7 @@
guard/1, otp_4886/1, otp_4988/1, otp_5091/1, otp_5276/1, otp_5338/1,
otp_5362/1, otp_5371/1, otp_7227/1, otp_5494/1, otp_5644/1, otp_5878/1,
otp_5917/1, otp_6585/1, otp_6885/1, otp_10436/1, otp_11254/1,
+ otp_11772/1,
export_all/1,
bif_clash/1,
behaviour_basic/1, behaviour_multiple/1,
@@ -86,7 +87,8 @@ all() ->
unsized_binary_in_bin_gen_pattern,
otp_4886, otp_4988, otp_5091, otp_5276, otp_5338,
otp_5362, otp_5371, otp_7227, otp_5494, otp_5644,
- otp_5878, otp_5917, otp_6585, otp_6885, otp_10436, otp_11254,export_all,
+ otp_5878, otp_5917, otp_6585, otp_6885, otp_10436, otp_11254,
+ otp_11772, export_all,
bif_clash, behaviour_basic, behaviour_multiple,
otp_7550, otp_8051, format_warn, {group, on_load},
too_many_arguments, basic_errors, bin_syntax_errors, predef, maps].
@@ -2562,7 +2564,7 @@ otp_10436(Config) when is_list(Config) ->
ok.
otp_11254(doc) ->
- "OTP-11254. Warnings for opaque types.";
+ "OTP-11254. M:F/A could crash the linter.";
otp_11254(suite) -> [];
otp_11254(Config) when is_list(Config) ->
Ts = <<"-module(p2).
@@ -2575,6 +2577,44 @@ otp_11254(Config) when is_list(Config) ->
run_test2(Config, Ts, []),
ok.
+otp_11772(doc) ->
+ "OTP-11772. Reintroduce warnings for redefined builtin types.";
+otp_11772(suite) -> [];
+otp_11772(Config) when is_list(Config) ->
+ Ts = <<"
+ -module(newly).
+
+ -compile(export_all).
+
+ %% Built-in:
+ -type node() :: node().
+ -type mfa() :: tuple().
+ -type gb_tree() :: mfa(). % Allowed since Erlang/OTP 17.0
+ -type digraph() :: [_]. % Allowed since Erlang/OTP 17.0
+
+ %% \"Newly\" introduced:
+ -type arity() :: atom().
+ -type bitstring() :: list().
+ -type iodata() :: integer().
+ -type boolean() :: iodata().
+
+ -type t() :: arity() | bitstring() | iodata() | boolean() | mfa()
+ | digraph() | gb_tree() | node().
+
+ -spec t() -> t().
+
+ t() ->
+ 1.
+ ">>,
+ {error,[{7,erl_lint,{builtin_type,{node,0}}},
+ {8,erl_lint,{builtin_type,{mfa,0}}}],
+ [{13,erl_lint,{new_builtin_type,{arity,0}}},
+ {14,erl_lint,{new_builtin_type,{bitstring,0}}},
+ {15,erl_lint,{new_builtin_type,{iodata,0}}},
+ {16,erl_lint,{new_builtin_type,{boolean,0}}}]} =
+ run_test2(Config, Ts, []),
+ ok.
+
export_all(doc) ->
"OTP-7392. Warning for export_all.";
export_all(Config) when is_list(Config) ->