diff options
-rw-r--r-- | bootstrap/lib/compiler/ebin/beam_bool.beam | bin | 16264 -> 16268 bytes | |||
-rw-r--r-- | bootstrap/lib/compiler/ebin/beam_utils.beam | bin | 13460 -> 13476 bytes | |||
-rw-r--r-- | bootstrap/lib/compiler/ebin/sys_core_fold.beam | bin | 49916 -> 50008 bytes | |||
-rw-r--r-- | bootstrap/lib/stdlib/ebin/erl_lint.beam | bin | 86612 -> 86960 bytes | |||
-rw-r--r-- | lib/compiler/doc/src/compile.xml | 10 | ||||
-rw-r--r-- | lib/compiler/src/beam_bool.erl | 12 | ||||
-rw-r--r-- | lib/compiler/src/beam_utils.erl | 2 | ||||
-rw-r--r-- | lib/compiler/src/sys_core_fold.erl | 9 | ||||
-rw-r--r-- | lib/compiler/test/guard_SUITE.erl | 12 | ||||
-rw-r--r-- | lib/compiler/test/receive_SUITE.erl | 1 | ||||
-rw-r--r-- | lib/dialyzer/test/small_SUITE_data/src/predef.erl | 4 | ||||
-rw-r--r-- | lib/stdlib/doc/src/supervisor.xml | 6 | ||||
-rw-r--r-- | lib/stdlib/src/erl_lint.erl | 62 | ||||
-rw-r--r-- | lib/stdlib/src/gen.erl | 6 | ||||
-rw-r--r-- | lib/stdlib/test/erl_lint_SUITE.erl | 50 | ||||
-rw-r--r-- | lib/stdlib/test/erl_lint_SUITE_data/predef.erl | 4 |
16 files changed, 135 insertions, 43 deletions
diff --git a/bootstrap/lib/compiler/ebin/beam_bool.beam b/bootstrap/lib/compiler/ebin/beam_bool.beam Binary files differindex 5d9de032ff..5ee89a6818 100644 --- a/bootstrap/lib/compiler/ebin/beam_bool.beam +++ b/bootstrap/lib/compiler/ebin/beam_bool.beam diff --git a/bootstrap/lib/compiler/ebin/beam_utils.beam b/bootstrap/lib/compiler/ebin/beam_utils.beam Binary files differindex 204a243a5b..8507db5454 100644 --- a/bootstrap/lib/compiler/ebin/beam_utils.beam +++ b/bootstrap/lib/compiler/ebin/beam_utils.beam diff --git a/bootstrap/lib/compiler/ebin/sys_core_fold.beam b/bootstrap/lib/compiler/ebin/sys_core_fold.beam Binary files differindex ffd15e985d..a664909bdc 100644 --- a/bootstrap/lib/compiler/ebin/sys_core_fold.beam +++ b/bootstrap/lib/compiler/ebin/sys_core_fold.beam diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam Binary files differindex 4e3acd3422..5bb81b1ed9 100644 --- a/bootstrap/lib/stdlib/ebin/erl_lint.beam +++ b/bootstrap/lib/stdlib/ebin/erl_lint.beam diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml index c66c8ea4bf..5fccdcdcb5 100644 --- a/lib/compiler/doc/src/compile.xml +++ b/lib/compiler/doc/src/compile.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2013</year> + <year>1996</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -551,6 +551,14 @@ module.beam: module.erl \ <c>{Module,Name,Arity}</c> or a list of such tuples.</p> </item> + <tag><c>nowarn_deprecated_type</c></tag> + <item> + <p>Turns off warnings for uses of deprecated types. By + default (<c>warn_deprecated_type</c>), warnings are + emitted for every use of a type known by the compiler + to be deprecated.</p> + </item> + <tag><c>warn_obsolete_guard</c></tag> <item> <p>Causes warnings to be emitted for calls to old type diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl index 590665514b..81b6d78864 100644 --- a/lib/compiler/src/beam_bool.erl +++ b/lib/compiler/src/beam_bool.erl @@ -393,10 +393,14 @@ bopt_tree([{set,_,_,{bif,'xor',_}}|_], _, _) -> throw('xor'); bopt_tree([{protected,[Dst],Code,_}|Is], Forest0, Pre) -> ProtForest0 = gb_trees:from_orddict([P || {_,any}=P <- gb_trees:to_list(Forest0)]), - {ProtPre,[{_,ProtTree}]} = bopt_tree(Code, ProtForest0, []), - Prot = {prot,ProtPre,ProtTree}, - Forest = gb_trees:enter(Dst, Prot, Forest0), - bopt_tree(Is, Forest, Pre); + case bopt_tree(Code, ProtForest0, []) of + {ProtPre,[{_,ProtTree}]} -> + Prot = {prot,ProtPre,ProtTree}, + Forest = gb_trees:enter(Dst, Prot, Forest0), + bopt_tree(Is, Forest, Pre); + _Res -> + throw(not_boolean_expr) + end; bopt_tree([{set,[Dst],[Src],move}=Move|Is], Forest, Pre) -> case {Src,Dst} of {{tmp,_},_} -> throw(move); diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index 27034aecce..8ca368c167 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -748,6 +748,8 @@ live_opt([{try_end,_}=I|Is], Regs, D, Acc) -> live_opt(Is, Regs, D, [I|Acc]); live_opt([{loop_rec_end,_}=I|Is], Regs, D, Acc) -> live_opt(Is, Regs, D, [I|Acc]); +live_opt([{wait_timeout,_,nil}=I|Is], Regs, D, Acc) -> + live_opt(Is, Regs, D, [I|Acc]); live_opt([{wait_timeout,_,{Tag,_}}=I|Is], Regs, D, Acc) when Tag =/= x -> live_opt(Is, Regs, D, [I|Acc]); live_opt([{line,_}=I|Is], Regs, D, Acc) -> diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 4ef345f563..6fdeea51d1 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -2362,6 +2362,15 @@ is_safe_bool_expr_1(#c_call{module=#c_literal{val=erlang}, %% been rewritten to is_record(Expr, LiteralTag, TupleSize). false; is_safe_bool_expr_1(#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}, + args=[A,#c_literal{val=Arity}]}, + Sub, _BoolVars) when is_integer(Arity), Arity >= 0 -> + is_safe_simple(A, Sub); +is_safe_bool_expr_1(#c_call{module=#c_literal{val=erlang}, + name=#c_literal{val=is_function}}, + _Sub, _BoolVars) -> + false; +is_safe_bool_expr_1(#c_call{module=#c_literal{val=erlang}, name=#c_literal{val=Name},args=Args}, Sub, BoolVars) -> NumArgs = length(Args), diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl index a0a9bb7ddd..eb205d09a7 100644 --- a/lib/compiler/test/guard_SUITE.erl +++ b/lib/compiler/test/guard_SUITE.erl @@ -33,7 +33,7 @@ tricky/1,rel_ops/1,literal_type_tests/1, basic_andalso_orelse/1,traverse_dcd/1, check_qlc_hrl/1,andalso_semi/1,t_tuple_size/1,binary_part/1, - bad_constants/1]). + bad_constants/1,bad_guards/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -50,7 +50,7 @@ groups() -> t_is_boolean,is_function_2,tricky,rel_ops, literal_type_tests,basic_andalso_orelse,traverse_dcd, check_qlc_hrl,andalso_semi,t_tuple_size,binary_part, - bad_constants]}]. + bad_constants,bad_guards]}]. init_per_suite(Config) -> Config. @@ -1023,6 +1023,10 @@ is_function_2(Config) when is_list(Config) -> true = is_function(id(fun() -> ok end), 0), false = is_function(id(fun ?MODULE:all/1), 0), false = is_function(id(fun() -> ok end), 1), + {'EXIT',{badarg,_}} = + (catch is_function(id(fun() -> ok end), -1) orelse error), + {'EXIT',{badarg,_}} = + (catch is_function(id(fun() -> ok end), '') orelse error), F = fun(_) -> ok end, if @@ -1550,6 +1554,10 @@ bad_constants(Config) when is_list(Config) -> ?line ?FAILING(3.14), ok. +bad_guards(Config) when is_list(Config) -> + if erlang:float(self()); true -> ok end, + ok. + %% Call this function to turn off constant propagation. id(I) -> I. diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl index ec49267ded..00a6e900d4 100644 --- a/lib/compiler/test/receive_SUITE.erl +++ b/lib/compiler/test/receive_SUITE.erl @@ -257,6 +257,7 @@ wait(Config) when is_list(Config) -> self() ! <<42>>, <<42>> = wait_1(r, 1, 2), {1,2,3} = wait_1(1, 2, 3), + {'EXIT',{timeout_value,_}} = (catch receive after [] -> timeout end), ok. wait_1(r, _, _) -> diff --git a/lib/dialyzer/test/small_SUITE_data/src/predef.erl b/lib/dialyzer/test/small_SUITE_data/src/predef.erl index c2364fd1c2..ee9073aa67 100644 --- a/lib/dialyzer/test/small_SUITE_data/src/predef.erl +++ b/lib/dialyzer/test/small_SUITE_data/src/predef.erl @@ -5,8 +5,8 @@ -export_type([array/0, digraph/0, gb_set/0]). -%% Before R17B local re-definitions of pre-defined opaque types were -%% ignored but did not generate any warning. +%% Before Erlang/OTP 17.0 local re-definitions of pre-defined opaque +%% types were ignored but did not generate any warning. -opaque array() :: atom(). -opaque digraph() :: atom(). -opaque gb_set() :: atom(). diff --git a/lib/stdlib/doc/src/supervisor.xml b/lib/stdlib/doc/src/supervisor.xml index 8197684d2d..3a5027d595 100644 --- a/lib/stdlib/doc/src/supervisor.xml +++ b/lib/stdlib/doc/src/supervisor.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2013</year> + <year>1996</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -262,12 +262,12 @@ child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules} locally as <c>Name</c> using <c>register/2</c>. If <c><anno>SupName</anno>={global,Name}</c> the supervisor is registered globally as <c>Name</c> using <c>global:register_name/2</c>. If - <c><anno>SupName</anno>={via,Module,Name}</c> the supervisor + <c><anno>SupName</anno>={via,<anno>Module</anno>,<anno>Name</anno>}</c> the supervisor is registered as <c>Name</c> using the registry represented by <c>Module</c>. The <c>Module</c> callback should export the functions <c>register_name/2</c>, <c>unregister_name/1</c> and <c>send/2</c>, which should behave like the corresponding functions in <c>global</c>. - Thus, <c>{via,global,Name}</c> is a valid reference.</p> + Thus, <c>{via,global,<anno>Name</anno>}</c> is a valid reference.</p> <p>If no name is provided, the supervisor is not registered.</p> <p><c><anno>Module</anno></c> is the name of the callback module.</p> <p><c><anno>Args</anno></c> is an arbitrary term which is passed as diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl index 9f5be2da37..5ba68318d7 100644 --- a/lib/stdlib/src/erl_lint.erl +++ b/lib/stdlib/src/erl_lint.erl @@ -344,10 +344,19 @@ format_error(spec_wrong_arity) -> "spec has the wrong arity"; format_error(callback_wrong_arity) -> "callback has the wrong arity"; -format_error({deprecated_type, {Name, Arity}, {Mod, NewName}, Rel}) -> +format_error({deprecated_builtin_type, {Name, Arity}, + Replacement, Rel}) -> + UseS = case Replacement of + {Mod, NewName} -> + io_lib:format("use ~w:~w/~w", [Mod, NewName, Arity]); + {Mod, NewName, NewArity} -> + io_lib:format("use ~w:~w/~w or preferably ~w:~w/~w", + [Mod, NewName, Arity, + Mod, NewName, NewArity]) + end, io_lib:format("type ~w/~w is deprecated and will be " - "removed in ~s; use ~w:~w/~w", - [Name, Arity, Rel, Mod, NewName, Arity]); + "removed in ~s; use ~s", + [Name, Arity, Rel, UseS]); format_error({not_exported_opaque, {TypeName, Arity}}) -> io_lib:format("opaque type ~w~s is not exported", [TypeName, gen_type_paren(Arity)]); @@ -499,6 +508,9 @@ start(File, Opts) -> {deprecated_function, bool_option(warn_deprecated_function, nowarn_deprecated_function, true, Opts)}, + {deprecated_type, + bool_option(warn_deprecated_type, nowarn_deprecated_type, + true, Opts)}, {obsolete_guard, bool_option(warn_obsolete_guard, nowarn_obsolete_guard, true, Opts)}, @@ -1852,6 +1864,10 @@ gexpr({op,Line,Op,A}, Vt, St0) -> true -> {Avt,St1}; false -> {Avt,add_error(Line, illegal_guard_expr, St1)} end; +gexpr({op,_,'andalso',L,R}, Vt, St) -> + gexpr_list([L,R], Vt, St); +gexpr({op,_,'orelse',L,R}, Vt, St) -> + gexpr_list([L,R], Vt, St); gexpr({op,Line,Op,L,R}, Vt, St0) -> {Avt,St1} = gexpr_list([L,R], Vt, St0), case is_gexpr_op(Op, 2) of @@ -1938,12 +1954,14 @@ is_gexpr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,F}]},As}, RDs) -> is_gexpr({call,L,{remote,Lt,{atom,Lm,erlang},{atom,Lf,F}},As}, RDs); is_gexpr({op,_L,Op,A}, RDs) -> is_gexpr_op(Op, 1) andalso is_gexpr(A, RDs); +is_gexpr({op,_L,'andalso',A1,A2}, RDs) -> + is_gexpr_list([A1,A2], RDs); +is_gexpr({op,_L,'orelse',A1,A2}, RDs) -> + is_gexpr_list([A1,A2], RDs); is_gexpr({op,_L,Op,A1,A2}, RDs) -> is_gexpr_op(Op, 2) andalso is_gexpr_list([A1,A2], RDs); is_gexpr(_Other, _RDs) -> false. -is_gexpr_op('andalso', 2) -> true; -is_gexpr_op('orelse', 2) -> true; is_gexpr_op(Op, A) -> try erl_internal:op_type(Op, A) of arith -> true; @@ -2637,10 +2655,11 @@ check_type({type, La, TypeName, Args}, SeenVars, St) -> St1 = case is_var_arity_type(TypeName) of true -> St; false -> - Obsolete = obsolete_type(TypePair), + Obsolete = (is_warn_enabled(deprecated_type, St) + andalso obsolete_builtin_type(TypePair)), IsObsolete = case Obsolete of - {deprecated, {M, _}, _} when M =/= Module -> + {deprecated, Repl, _} when element(1, Repl) =/= Module -> case dict:find(TypePair, Types) of {ok, _} -> false; error -> true @@ -2650,7 +2669,8 @@ check_type({type, La, TypeName, Args}, SeenVars, St) -> case IsObsolete of true -> {deprecated, Replacement, Rel} = Obsolete, - W = {deprecated_type, TypePair, Replacement, Rel}, + Tag = deprecated_builtin_type, + W = {Tag, TypePair, Replacement, Rel}, add_warning(La, W, St); false -> OldUsed = Usage#usage.used_types, @@ -2780,15 +2800,23 @@ is_newly_introduced_builtin_type({boolean, 0}) -> true; is_newly_introduced_builtin_type({Name, _}) when is_atom(Name) -> false. %% Obsolete in OTP 17.0. -obsolete_type({array, 0}) -> {deprecated, {array, array}, "OTP 18.0"}; -obsolete_type({dict, 0}) -> {deprecated, {dict, dict}, "OTP 18.0"}; -obsolete_type({digraph, 0}) -> {deprecated, {digraph, graph}, "OTP 18.0"}; -obsolete_type({gb_set, 0}) -> {deprecated, {gb_sets, set}, "OTP 18.0"}; -obsolete_type({gb_tree, 0}) -> {deprecated, {gb_trees, tree}, "OTP 18.0"}; -obsolete_type({queue, 0}) -> {deprecated, {queue, queue}, "OTP 18.0"}; -obsolete_type({set, 0}) -> {deprecated, {sets, set}, "OTP 18.0"}; -obsolete_type({tid, 0}) -> {deprecated, {ets, tid}, "OTP 18.0"}; -obsolete_type({Name, _}) when is_atom(Name) -> no. +obsolete_builtin_type({array, 0}) -> + {deprecated, {array, array, 1}, "OTP 18.0"}; +obsolete_builtin_type({dict, 0}) -> + {deprecated, {dict, dict, 2}, "OTP 18.0"}; +obsolete_builtin_type({digraph, 0}) -> + {deprecated, {digraph, graph}, "OTP 18.0"}; +obsolete_builtin_type({gb_set, 0}) -> + {deprecated, {gb_sets, set, 1}, "OTP 18.0"}; +obsolete_builtin_type({gb_tree, 0}) -> + {deprecated, {gb_trees, tree, 2}, "OTP 18.0"}; +obsolete_builtin_type({queue, 0}) -> + {deprecated, {queue, queue, 1}, "OTP 18.0"}; +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. %% spec_decl(Line, Fun, Types, State) -> State. diff --git a/lib/stdlib/src/gen.erl b/lib/stdlib/src/gen.erl index 7281549ea7..63116fa16e 100644 --- a/lib/stdlib/src/gen.erl +++ b/lib/stdlib/src/gen.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -37,7 +37,9 @@ %%----------------------------------------------------------------- -type linkage() :: 'link' | 'nolink'. --type emgr_name() :: {'local', atom()} | {'global', term()} | {via, atom(), term()}. +-type emgr_name() :: {'local', atom()} + | {'global', term()} + | {'via', Module :: module(), Name :: term()}. -type start_ret() :: {'ok', pid()} | 'ignore' | {'error', term()}. diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl index 1614a2722f..5e117409de 100644 --- a/lib/stdlib/test/erl_lint_SUITE.erl +++ b/lib/stdlib/test/erl_lint_SUITE.erl @@ -1494,7 +1494,15 @@ guard(Config) when is_list(Config) -> [], {errors,[{1,erl_lint,illegal_guard_expr}, {2,erl_lint,illegal_guard_expr}, - {3,erl_lint,illegal_guard_expr}],[]}} + {3,erl_lint,illegal_guard_expr}],[]}}, + {guard9, + <<"t(X, Y) when erlang:'andalso'(X, Y) -> ok; + t(X, Y) when erlang:'orelse'(X, Y) -> ok. + ">>, + [], + {errors,[{1,erl_lint,illegal_guard_expr}, + {2,erl_lint,illegal_guard_expr}], + []}} ], ?line [] = run(Config, Ts1), ok. @@ -3243,20 +3251,42 @@ bin_syntax_errors(Config) -> ok. predef(doc) -> - "Predefined types: array(), digraph(), and so on"; + "OTP-10342: Predefined types: array(), digraph(), and so on"; predef(suite) -> []; predef(Config) when is_list(Config) -> W = get_compilation_warnings(Config, "predef", []), [] = W, W2 = get_compilation_warnings(Config, "predef2", []), - [{7,erl_lint,{deprecated_type,{array,0},{array,array},"OTP 18.0"}}, - {12,erl_lint,{deprecated_type,{dict,0},{dict,dict},"OTP 18.0"}}, - {17,erl_lint,{deprecated_type,{digraph,0},{digraph,graph},"OTP 18.0"}}, - {27,erl_lint,{deprecated_type,{gb_set,0},{gb_sets,set},"OTP 18.0"}}, - {32,erl_lint,{deprecated_type,{gb_tree,0},{gb_trees,tree},"OTP 18.0"}}, - {37,erl_lint,{deprecated_type,{queue,0},{queue,queue},"OTP 18.0"}}, - {42,erl_lint,{deprecated_type,{set,0},{sets,set},"OTP 18.0"}}, - {47,erl_lint,{deprecated_type,{tid,0},{ets,tid},"OTP 18.0"}}] = W2, + Tag = deprecated_builtin_type, + [{7,erl_lint,{Tag,{array,0},{array,array,1},"OTP 18.0"}}, + {12,erl_lint,{Tag,{dict,0},{dict,dict,2},"OTP 18.0"}}, + {17,erl_lint,{Tag,{digraph,0},{digraph,graph},"OTP 18.0"}}, + {27,erl_lint,{Tag,{gb_set,0},{gb_sets,set,1},"OTP 18.0"}}, + {32,erl_lint,{Tag,{gb_tree,0},{gb_trees,tree,2},"OTP 18.0"}}, + {37,erl_lint,{Tag,{queue,0},{queue,queue,1},"OTP 18.0"}}, + {42,erl_lint,{Tag,{set,0},{sets,set,1},"OTP 18.0"}}, + {47,erl_lint,{Tag,{tid,0},{ets,tid},"OTP 18.0"}}] = W2, + Ts = [{otp_10342_1, + <<"-compile(nowarn_deprecated_type). + + -spec t(dict()) -> non_neg_integer(). + + t(D) -> + erlang:phash2(D, 3000). + ">>, + {[nowarn_unused_function]}, + []}, + {otp_10342_2, + <<"-spec t(dict()) -> non_neg_integer(). + + t(D) -> + erlang:phash2(D, 3000). + ">>, + {[nowarn_unused_function]}, + {warnings,[{1,erl_lint, + {deprecated_builtin_type,{dict,0},{dict,dict,2}, + "OTP 18.0"}}]}}], + [] = run(Config, Ts), ok. run(Config, Tests) -> diff --git a/lib/stdlib/test/erl_lint_SUITE_data/predef.erl b/lib/stdlib/test/erl_lint_SUITE_data/predef.erl index c2364fd1c2..ee9073aa67 100644 --- a/lib/stdlib/test/erl_lint_SUITE_data/predef.erl +++ b/lib/stdlib/test/erl_lint_SUITE_data/predef.erl @@ -5,8 +5,8 @@ -export_type([array/0, digraph/0, gb_set/0]). -%% Before R17B local re-definitions of pre-defined opaque types were -%% ignored but did not generate any warning. +%% Before Erlang/OTP 17.0 local re-definitions of pre-defined opaque +%% types were ignored but did not generate any warning. -opaque array() :: atom(). -opaque digraph() :: atom(). -opaque gb_set() :: atom(). |