diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/common_test/src/ct_logs.erl | 66 | ||||
-rw-r--r-- | lib/compiler/src/sys_core_fold.erl | 17 | ||||
-rw-r--r-- | lib/compiler/test/fun_SUITE.erl | 30 | ||||
-rw-r--r-- | lib/dialyzer/src/dialyzer_dep.erl | 62 | ||||
-rw-r--r-- | lib/dialyzer/vsn.mk | 2 | ||||
-rw-r--r-- | lib/reltool/doc/src/notes.xml | 10 | ||||
-rw-r--r-- | lib/reltool/doc/src/reltool.xml | 10 | ||||
-rw-r--r-- | lib/ssl/test/ssl_test_lib.erl | 6 | ||||
-rw-r--r-- | lib/stdlib/src/otp_internal.erl | 2 | ||||
-rw-r--r-- | lib/stdlib/test/erl_lint_SUITE.erl | 6 | ||||
-rw-r--r-- | lib/syntax_tools/doc/src/notes.xml | 4 | ||||
-rw-r--r-- | lib/syntax_tools/vsn.mk | 2 |
12 files changed, 139 insertions, 78 deletions
diff --git a/lib/common_test/src/ct_logs.erl b/lib/common_test/src/ct_logs.erl index 29b38e9748..e6d683c8a9 100644 --- a/lib/common_test/src/ct_logs.erl +++ b/lib/common_test/src/ct_logs.erl @@ -269,7 +269,7 @@ cast(Msg) -> %%% <p>This function is called by ct_framework:init_tc/3</p> init_tc(RefreshLog) -> call({init_tc,self(),group_leader(),RefreshLog}), - io:format(["$tc_html",xhtml("", "<br />")]), + tc_io_format(group_leader(), xhtml("", "<br />"), []), ok. %%%----------------------------------------------------------------- @@ -800,7 +800,8 @@ logger_loop(State) -> %% make sure no IO for this test case from the %% CT logger gets rejected test_server:permit_io(GL, self()), - print_style(GL,GL,State#logger_state.stylesheet), + IoFormat = fun tc_io_format/3, + print_style(GL, IoFormat, State#logger_state.stylesheet), set_evmgr_gl(GL), TCGLs = add_tc_gl(TCPid,GL,State), if not RefreshLog -> @@ -931,7 +932,7 @@ print_to_log(sync, FromPid, Category, TCGL, Content, EscChars, State) -> if FromPid /= TCGL -> IoFun = create_io_fun(FromPid, CtLogFd, EscChars), IoList = lists:foldl(IoFun, [], Content), - try io:format(TCGL,["$tc_html","~ts"], [IoList]) of + try tc_io_format(TCGL, "~ts", [IoList]) of ok -> ok catch _:_ -> @@ -962,7 +963,7 @@ print_to_log(async, FromPid, Category, TCGL, Content, EscChars, State) -> case erlang:is_process_alive(TCGL) of true -> - try io:format(TCGL, ["$tc_html","~ts"], + try tc_io_format(TCGL, "~ts", [lists:foldl(IoFun,[],Content)]) of _ -> ok catch @@ -1113,27 +1114,25 @@ open_ctlog(MiscIoName) -> "View I/O logged after the test run</a></li>\n</ul>\n", [MiscIoName,MiscIoName]), - print_style(Fd,group_leader(),undefined), + print_style(Fd, fun io:format/3, undefined), io:format(Fd, xhtml("<br><h2>Progress Log</h2>\n<pre>\n", "<br />\n<h4>PROGRESS LOG</h4>\n<pre>\n"), []), Fd. -print_style(Fd,GL,undefined) -> +print_style(Fd, IoFormat, undefined) -> case basic_html() of true -> Style = "<style>\n div.ct_internal { background:lightgrey; color:black; }\n div.default { background:lightgreen; color:black; }\n </style>\n", - if Fd == GL -> io:format(["$tc_html",Style], []); - true -> io:format(Fd, Style, []) - end; + IoFormat(Fd, Style, []); _ -> ok end; -print_style(Fd,GL,StyleSheet) -> +print_style(Fd, IoFormat, StyleSheet) -> case file:read_file(StyleSheet) of {ok,Bin} -> Str = b2s(Bin,encoding(StyleSheet)), @@ -1146,36 +1145,55 @@ print_style(Fd,GL,StyleSheet) -> N1 -> N1 end, if (Pos0 == 0) and (Pos1 /= 0) -> - print_style_error(Fd,GL,StyleSheet,missing_style_start_tag); + print_style_error(Fd, IoFormat, + StyleSheet, missing_style_start_tag); (Pos0 /= 0) and (Pos1 == 0) -> - print_style_error(Fd,GL,StyleSheet,missing_style_end_tag); + print_style_error(Fd, IoFormat, + StyleSheet,missing_style_end_tag); Pos0 /= 0 -> Style = string:sub_string(Str,Pos0,Pos1+7), - if Fd == GL -> io:format(Fd,["$tc_html","~ts\n"],[Style]); - true -> io:format(Fd,"~ts\n",[Style]) - end; + IoFormat(Fd,"~ts\n",[Style]); Pos0 == 0 -> - if Fd == GL -> io:format(Fd,["$tc_html","<style>\n~ts</style>\n"],[Str]); - true -> io:format(Fd,"<style>\n~ts</style>\n",[Str]) - end + IoFormat(Fd,"<style>\n~ts</style>\n",[Str]) end; {error,Reason} -> - print_style_error(Fd,GL,StyleSheet,Reason) + print_style_error(Fd,IoFormat,StyleSheet,Reason) end. -print_style_error(Fd,GL,StyleSheet,Reason) -> +print_style_error(Fd, IoFormat, StyleSheet, Reason) -> IO = io_lib:format("\n<!-- Failed to load stylesheet ~ts: ~p -->\n", [StyleSheet,Reason]), - if Fd == GL -> io:format(Fd,["$tc_html",IO],[]); - true -> io:format(Fd,IO,[]) - end, - print_style(Fd,GL,undefined). + IoFormat(Fd, IO, []), + print_style(Fd, IoFormat, undefined). close_ctlog(Fd) -> io:format(Fd, "\n</pre>\n", []), io:format(Fd, [xhtml("<br><br>\n", "<br /><br />\n") | footer()], []), file:close(Fd). +%%%----------------------------------------------------------------- +%%% tc_io_format/3 +%%% Tell common_test's IO server (group leader) not to escape +%%% HTML characters. + +-spec tc_io_format(io:device(), io:format(), [term()]) -> 'ok'. + +tc_io_format(Fd, Format0, Args) -> + %% We know that the specially wrapped format string is handled + %% by our IO server, but Dialyzer does not and would tell us + %% that the call to io:format/3 would fail. Therefore, we must + %% fool dialyzer. + + Format = case cloaked_true() of + true -> ["$tc_html",Format0]; + false -> Format0 %Never happens. + end, + io:format(Fd, Format, Args). + +%% Return 'true', but let dialyzer think that a boolean is returned. +cloaked_true() -> + is_process_alive(self()). + %%%----------------------------------------------------------------- %%% Make an index page for the last run diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index b5b8d8a8ec..dbc27db377 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -374,10 +374,21 @@ expr(#c_receive{clauses=Cs0,timeout=T0,action=A0}=Recv, Ctxt, Sub) -> T1 = expr(T0, value, Sub), A1 = body(A0, Ctxt, Sub), Recv#c_receive{clauses=Cs1,timeout=T1,action=A1}; -expr(#c_apply{op=Op0,args=As0}=App, _, Sub) -> +expr(#c_apply{anno=Anno,op=Op0,args=As0}=App, _, Sub) -> Op1 = expr(Op0, value, Sub), As1 = expr_list(As0, value, Sub), - App#c_apply{op=Op1,args=As1}; + case Op1 of + #c_var{} -> + App#c_apply{op=Op1,args=As1}; + _ -> + add_warning(App, invalid_call), + Err = #c_call{anno=Anno, + module=#c_literal{val=erlang}, + name=#c_literal{val=error}, + args=[#c_tuple{es=[#c_literal{val='badfun'}, + Op1]}]}, + make_effect_seq(As1++[Err], Sub) + end; expr(#c_call{module=M0,name=N0}=Call0, Ctxt, Sub) -> M1 = expr(M0, value, Sub), N1 = expr(N0, value, Sub), @@ -3395,6 +3406,8 @@ format_error({no_effect,{erlang,F,A}}) -> format_error(result_ignored) -> "the result of the expression is ignored " "(suppress the warning by assigning the expression to the _ variable)"; +format_error(invalid_call) -> + "invalid function call"; format_error(useless_building) -> "a term is constructed, but never used"; format_error(bin_opt_alias) -> diff --git a/lib/compiler/test/fun_SUITE.erl b/lib/compiler/test/fun_SUITE.erl index 17ff8601d9..16474adf5b 100644 --- a/lib/compiler/test/fun_SUITE.erl +++ b/lib/compiler/test/fun_SUITE.erl @@ -22,7 +22,7 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, test1/1,overwritten_fun/1,otp_7202/1,bif_fun/1, - external/1,eep37/1,eep37_dup/1,badarity/1]). + external/1,eep37/1,eep37_dup/1,badarity/1,badfun/1]). %% Internal exports. -export([call_me/1,dup1/0,dup2/0]). @@ -33,10 +33,12 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> test_lib:recompile(?MODULE), - [test1,overwritten_fun,otp_7202,bif_fun,external,eep37,eep37_dup,badarity]. + [{group,p}]. -groups() -> - []. +groups() -> + [{p,[parallel], + [test1,overwritten_fun,otp_7202,bif_fun,external,eep37, + eep37_dup,badarity,badfun]}]. init_per_suite(Config) -> Config. @@ -221,5 +223,25 @@ badarity(Config) when is_list(Config) -> {'EXIT',{{badarity,{_,[]}},_}} = (catch (fun badarity/1)()), ok. +badfun(_Config) -> + X = not_a_fun, + expect_badfun(42, catch 42()), + expect_badfun(42.0, catch 42.0(1)), + expect_badfun(X, catch X()), + expect_badfun(X, catch X(1)), + Len = length(atom_to_list(X)), + expect_badfun(Len, catch begin length(atom_to_list(X)) end(1)), + + expect_badfun(42, catch 42(put(?FUNCTION_NAME, yes))), + yes = erase(?FUNCTION_NAME), + + expect_badfun(X, catch X(put(?FUNCTION_NAME, of_course))), + of_course = erase(?FUNCTION_NAME), + + ok. + +expect_badfun(Term, Exit) -> + {'EXIT',{{badfun,Term},_}} = Exit. + id(I) -> I. diff --git a/lib/dialyzer/src/dialyzer_dep.erl b/lib/dialyzer/src/dialyzer_dep.erl index 6678037bc0..273c05c54c 100644 --- a/lib/dialyzer/src/dialyzer_dep.erl +++ b/lib/dialyzer/src/dialyzer_dep.erl @@ -59,8 +59,14 @@ %% separately. %% --spec analyze(cerl:c_module()) -> - {dict:dict(), ordsets:ordset('external' | label()), dict:dict(), dict:dict()}. +-type dep_ordset() :: ordsets:ordset(label() | 'external'). + +-type deps() :: dict:dict(label() | 'external' | 'top', dep_ordset()). +-type esc() :: dep_ordset(). +-type calls() :: dict:dict(label(), ordsets:ordset(label())). +-type letrecs() :: dict:dict(label(), label()). + +-spec analyze(cerl:c_module()) -> {deps(), esc(), calls(), letrecs()}. analyze(Tree) -> %% io:format("Handling ~w\n", [cerl:atom_val(cerl:module_name(Tree))]), @@ -79,22 +85,26 @@ traverse(Tree, Out, State, CurrentFun) -> apply -> Op = cerl:apply_op(Tree), Args = cerl:apply_args(Tree), - %% Op is always a variable and should not be marked as escaping - %% based on its use. case var =:= cerl:type(Op) of - false -> erlang:error({apply_op_not_a_variable, cerl:type(Op)}); - true -> ok - end, - OpFuns = case map__lookup(cerl_trees:get_label(Op), Out) of - none -> output(none); - {value, OF} -> OF - end, - {ArgFuns, State2} = traverse_list(Args, Out, State, CurrentFun), - State3 = state__add_esc(merge_outs(ArgFuns), State2), - State4 = state__add_deps(CurrentFun, OpFuns, State3), - State5 = state__store_callsite(cerl_trees:get_label(Tree), - OpFuns, length(Args), State4), - {output(set__singleton(external)), State5}; + false -> + %% We have discovered an error here, but we ignore it and let + %% later passes handle it; we do not modify the dependencies. + %% erlang:error({apply_op_not_a_variable, cerl:type(Op)}); + {output(none), State}; + true -> + %% Op is a variable and should not be marked as escaping + %% based on its use. + OpFuns = case map__lookup(cerl_trees:get_label(Op), Out) of + none -> output(none); + {value, OF} -> OF + end, + {ArgFuns, State2} = traverse_list(Args, Out, State, CurrentFun), + State3 = state__add_esc(merge_outs(ArgFuns), State2), + State4 = state__add_deps(CurrentFun, OpFuns, State3), + State5 = state__store_callsite(cerl_trees:get_label(Tree), + OpFuns, length(Args), State4), + {output(set__singleton(external)), State5} + end; binary -> {output(none), State}; 'case' -> @@ -481,11 +491,11 @@ all_vars(Tree, AccIn) -> -type local_set() :: 'none' | #set{}. --record(state, {deps :: dict:dict(), +-record(state, {deps :: deps(), esc :: local_set(), - call :: dict:dict(), - arities :: dict:dict(), - letrecs :: dict:dict()}). + calls :: calls(), + arities :: dict:dict(label() | 'top', arity()), + letrecs :: letrecs()}). state__new(Tree) -> Exports = set__from_list([X || X <- cerl:module_exports(Tree)]), @@ -503,7 +513,7 @@ state__new(Tree) -> %% init the escaping function labels to exported + called from on_load InitEsc = set__from_list(OnLoadLs ++ ExpLs), Arities = cerl_trees:fold(fun find_arities/2, dict:new(), Tree), - #state{deps = map__new(), esc = InitEsc, call = map__new(), + #state{deps = map__new(), esc = InitEsc, calls = map__new(), arities = Arities, letrecs = map__new()}. find_arities(Tree, AccMap) -> @@ -518,7 +528,7 @@ find_arities(Tree, AccMap) -> state__add_deps(_From, #output{content = none}, State) -> State; -state__add_deps(From, #output{type = single, content=To}, +state__add_deps(From, #output{type = single, content = To}, #state{deps = Map} = State) -> %% io:format("Adding deps from ~w to ~w\n", [From, set__to_ordsets(To)]), State#state{deps = map__add(From, To, Map)}. @@ -544,16 +554,16 @@ state__esc(#state{esc = Esc}) -> state__store_callsite(_From, #output{content = none}, _CallArity, State) -> State; state__store_callsite(From, To, CallArity, - #state{call = Calls, arities = Arities} = State) -> + #state{calls = Calls, arities = Arities} = State) -> Filter = fun(external) -> true; (Fun) -> CallArity =:= dict:fetch(Fun, Arities) end, case filter_outs(To, Filter) of #output{content = none} -> State; - To1 -> State#state{call = map__store(From, To1, Calls)} + To1 -> State#state{calls = map__store(From, To1, Calls)} end. -state__calls(#state{call = Calls}) -> +state__calls(#state{calls = Calls}) -> Calls. %%------------------------------------------------------------ diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk index 77ea9d0413..077fe01e85 100644 --- a/lib/dialyzer/vsn.mk +++ b/lib/dialyzer/vsn.mk @@ -1 +1 @@ -DIALYZER_VSN = 2.10 +DIALYZER_VSN = 3.0 diff --git a/lib/reltool/doc/src/notes.xml b/lib/reltool/doc/src/notes.xml index 082079aa74..0a83954865 100644 --- a/lib/reltool/doc/src/notes.xml +++ b/lib/reltool/doc/src/notes.xml @@ -194,7 +194,6 @@ <section><title>Fixed Bugs and Malfunctions</title> <list> <item> - <p> <list> <item> If <c>incl_cond</c> was set to <c>derived</c> on module level, then reltool_server would crash with a <c>case_clause</c>. This has been corrected. @@ -225,7 +224,7 @@ implemented in reltool. </item> <item> Instead of only looking at the directory name, reltool now first looks for a <c>.app</c> file in order to figure out the name of - an application. </item> </list></p> + an application. </item> </list> <p> Own Id: OTP-10012 Aux Id: kunagi-171 [82] </p> </item> @@ -272,7 +271,6 @@ <section><title>Fixed Bugs and Malfunctions</title> <list> <item> - <p> Miscellaneous corrections: <list> <item> Start of reltool GUI would sometimes crash with a badmatch in reltool_sys_win:do_init. This has been corrected. </item> @@ -311,7 +309,7 @@ and when generating target system. </item> <item> Title of dependecies column in app and mod window is changed from "Modules used by others" to "Modules using this". - </item> </list></p> + </item> </list> <p> Own Id: OTP-9792</p> </item> @@ -338,7 +336,7 @@ </item> <item> <p> - Some bug fixes related to the handling of escripts: + Some bug fixes related to the handling of escripts:</p> <list> <item> Reltool could not handle escripts with inlined applications. This has been corrected. Inlined applications will be visible in the GUI, but not possible @@ -357,7 +355,7 @@ another escript, for which the name sorts before the existing one, would cause reltool to fail saying "Application name clash". This has been corrected. - </item> </list></p> + </item> </list> <p> Own Id: OTP-9968</p> </item> diff --git a/lib/reltool/doc/src/reltool.xml b/lib/reltool/doc/src/reltool.xml index f4effc3f2e..38448e7961 100644 --- a/lib/reltool/doc/src/reltool.xml +++ b/lib/reltool/doc/src/reltool.xml @@ -248,7 +248,7 @@ <p>When starting this release, three things must be specified:</p> <taglist> - <tag><b>Which <c>releases</c> directory to use</b></tag> + <tag><em>Which <c>releases</c> directory to use</em></tag> <item>Tell the release handler to use the <c>releases</c> directory in our target structure instead of <c>$OTP_ROOT/releases</c>. This is done by setting the SASL @@ -257,7 +257,7 @@ <target-dir>/releases</c>) or in <c>sys.config</c>.</item> - <tag><b>Which boot file to use</b></tag> + <tag><em>Which boot file to use</em></tag> <item>The default boot file is <c>$OTP_ROOT/bin/start</c>, but in this case we need to specify a boot file from our target structure, typically @@ -265,7 +265,7 @@ is done with the <c>-boot</c> command line option to <c>erl</c></item> - <tag><b>The location of our applications</b></tag> + <tag><em>The location of our applications</em></tag> <item>The generated .script (and .boot) file uses the environment variable <c>$RELTOOL_EXT_LIB</c> as prefix for the paths to all applications. The <c>-boot_var</c> option @@ -275,8 +275,8 @@ </taglist> <p>Example:</p> - <p><code>erl -sasl releases_dir \"mytarget/releases\" -boot mytarget/releases/1.0/myrel\ - -boot_var RELTOOL_EXT_LIB mytarget/lib</code></p> + <code>erl -sasl releases_dir \"mytarget/releases\" -boot mytarget/releases/1.0/myrel\ + -boot_var RELTOOL_EXT_LIB mytarget/lib</code> </item> <tag><c>incl_sys_filters</c></tag> diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl index 38cc3532d8..02fdc4330f 100644 --- a/lib/ssl/test/ssl_test_lib.erl +++ b/lib/ssl/test/ssl_test_lib.erl @@ -386,11 +386,11 @@ cert_options(Config) -> SNIServerBCertFile = filename:join([?config(priv_dir, Config), "b.server", "cert.pem"]), SNIServerBKeyFile = filename:join([?config(priv_dir, Config), "b.server", "key.pem"]), [{client_opts, []}, - {client_verification_opts, [{cacertfile, ClientCaCertFile}, + {client_verification_opts, [{cacertfile, ServerCaCertFile}, {certfile, ClientCertFile}, {keyfile, ClientKeyFile}, {ssl_imp, new}]}, - {client_verification_opts_digital_signature_only, [{cacertfile, ClientCaCertFile}, + {client_verification_opts_digital_signature_only, [{cacertfile, ServerCaCertFile}, {certfile, ClientCertFileDigitalSignatureOnly}, {keyfile, ClientKeyFile}, {ssl_imp, new}]}, @@ -426,7 +426,7 @@ cert_options(Config) -> {user_lookup_fun, {fun user_lookup/3, undefined}}, {ciphers, srp_anon_suites()}]}, {server_verification_opts, [{ssl_imp, new},{reuseaddr, true}, - {cacertfile, ServerCaCertFile}, + {cacertfile, ClientCaCertFile}, {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]}, {client_kc_opts, [{certfile, ClientKeyCertFile}, {ssl_imp, new}]}, {server_kc_opts, [{ssl_imp, new},{reuseaddr, true}, diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl index 7a59523f06..c3ad261daa 100644 --- a/lib/stdlib/src/otp_internal.erl +++ b/lib/stdlib/src/otp_internal.erl @@ -35,7 +35,7 @@ obsolete(Module, Name, Arity) -> case obsolete_1(Module, Name, Arity) of {deprecated=Tag,{_,_,_}=Replacement} -> - {Tag,Replacement,"in a future release"}; + {Tag,Replacement,"a future release"}; {_,String}=Ret when is_list(String) -> Ret; {_,_,_}=Ret -> diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl index b0214e5238..d916eb3eef 100644 --- a/lib/stdlib/test/erl_lint_SUITE.erl +++ b/lib/stdlib/test/erl_lint_SUITE.erl @@ -2003,7 +2003,7 @@ otp_5362(Config) when is_list(Config) -> {error, [{5,erl_lint,{call_to_redefined_old_bif,{spawn,1}}}], [{4,erl_lint,{deprecated,{erlang,hash,2},{erlang,phash2,2}, - "in a future release"}}]}}, + "a future release"}}]}}, {otp_5362_5, <<"-compile(nowarn_deprecated_function). @@ -2063,7 +2063,7 @@ otp_5362(Config) when is_list(Config) -> {nowarn_bif_clash,{spawn,1}}]}, % has no effect {warnings, [{5,erl_lint,{deprecated,{erlang,hash,2},{erlang,phash2,2}, - "in a future release"}}]}}, + "a future release"}}]}}, {otp_5362_9, <<"-include_lib(\"stdlib/include/qlc.hrl\"). @@ -2093,7 +2093,7 @@ otp_5362(Config) when is_list(Config) -> [], {warnings, [{1,erl_lint,{deprecated,{erlang,hash,2}, - {erlang,phash2,2},"in a future release"}}]}}, + {erlang,phash2,2},"a future release"}}]}}, {call_removed_function, <<"t(X) -> regexp:match(X).">>, diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml index 406a6c071b..78b2c7c7a4 100644 --- a/lib/syntax_tools/doc/src/notes.xml +++ b/lib/syntax_tools/doc/src/notes.xml @@ -76,11 +76,11 @@ <p> Teach Maps to erl_syntax</p> <p> - Affected functions: <list> + Affected functions:</p> <list> <item>erl_syntax:abstract/1</item> <item>erl_syntax:concrete/1</item> <item>erl_syntax:is_leaf/1</item> - <item>erl_syntax:is_literal/1</item> </list></p> + <item>erl_syntax:is_literal/1</item> </list> <p> Own Id: OTP-12265</p> </item> diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk index 403e90196e..f09c2a01d0 100644 --- a/lib/syntax_tools/vsn.mk +++ b/lib/syntax_tools/vsn.mk @@ -1 +1 @@ -SYNTAX_TOOLS_VSN = 1.7 +SYNTAX_TOOLS_VSN = 2.0 |