From a1717af197bc01663d85e9eecef41f4bcea77248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 20 Oct 2022 08:53:16 +0200 Subject: Fix filelib_SUITE:ensure_path_invalid_path/1 --- lib/stdlib/test/filelib_SUITE.erl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl index eac0dea4d8..179567f128 100644 --- a/lib/stdlib/test/filelib_SUITE.erl +++ b/lib/stdlib/test/filelib_SUITE.erl @@ -493,7 +493,16 @@ ensure_path_invalid_path(Config) when is_list(Config) -> FileName = filename:join(BaseDir, "foo"), ok = file:write_file(FileName, <<"eh?\n">>), Path = filename:join(FileName, "foo/bar/baz"), - {error,enotdir} = filelib:ensure_path(Path), + case filelib:ensure_path(Path) of + {error,enotdir} -> + ok; + {error,enoent} -> + %% The documentation has the following to say about the + %% `enotdir` error reason: + %% + %% "On some platforms, enoent is returned instead." + ok + end, false = filelib:is_dir(Path). ensure_path_relative_path(Config) when is_list(Config) -> -- cgit v1.2.1 From 8cb8d3d5d6ec15c4e8f27366b72baffde39485f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Wed, 26 Oct 2022 09:34:41 +0200 Subject: asn1, compiler: Avoid running out of memory on Windows If a test machine has many CPU cores but is running the 32-bit version of Windows, some of the memory-intensive tests such a compile_SUITE:core_roundtrip/1 can easily run out of memory if all cores are used. Avoid this by limiting the number of parallel processes started by asn1_test_lib:p_run/2 and test_lib:p_run/2. --- lib/asn1/test/asn1_test_lib.erl | 9 ++++++++- lib/compiler/test/test_lib.erl | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/asn1/test/asn1_test_lib.erl b/lib/asn1/test/asn1_test_lib.erl index 0a331d0dd0..d421c29dd3 100644 --- a/lib/asn1/test/asn1_test_lib.erl +++ b/lib/asn1/test/asn1_test_lib.erl @@ -306,7 +306,14 @@ ber_get_len(<<1:1,Octets:7,T0/binary>>) -> %% Will fail the test case if there were any errors. p_run(Test, List) -> - S = erlang:system_info(schedulers), + %% Limit the number of parallel processes to avoid running out of + %% memory. + S = case {erlang:system_info(schedulers),erlang:system_info(wordsize)} of + {S0,4} -> + min(S0, 2); + {S0,_} -> + min(S0, 8) + end, N = case test_server:is_cover() of false -> S + 1; diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl index 7182dd6555..0328ed9f26 100644 --- a/lib/compiler/test/test_lib.erl +++ b/lib/compiler/test/test_lib.erl @@ -157,7 +157,14 @@ highest_opcode(Beam) -> %% Will fail the test case if there were any errors. p_run(Test, List) -> - S = erlang:system_info(schedulers), + %% Limit the number of parallel processes to avoid running out of + %% memory. + S = case {erlang:system_info(schedulers),erlang:system_info(wordsize)} of + {S0,4} -> + min(S0, 2); + {S0,8} -> + min(S0, 8) + end, N = S + 1, io:format("p_run: ~p parallel processes\n", [N]), p_run_loop(Test, List, N, [], 0, 0). -- cgit v1.2.1 From 75bfcc3e21fdb3e517c4823cbfb225a1ea13c4d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Mon, 31 Oct 2022 14:14:40 +0100 Subject: compile_SUITE: Avoid eaccess error during cleanup on Windows --- lib/compiler/test/compile_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index abd873b8d2..0071fb3dc1 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.erl @@ -676,7 +676,7 @@ encrypted_abstr(Config) when is_list(Config) -> %% Now run the tests that require crypto. encrypted_abstr_1(Simple, Target), ok = file:delete(Target), - ok = file:del_dir_r(filename:dirname(Target)) + _ = file:del_dir_r(filename:dirname(Target)) end, %% Cleanup. -- cgit v1.2.1 From 4551d6bbcfd417ff46b7294a88366f7d1c955d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Tue, 1 Nov 2022 14:49:32 +0100 Subject: compile_SUITE: Make core_roundtrip/1 less resource-intensive --- lib/compiler/test/compile_SUITE.erl | 13 +++++++++++-- lib/compiler/test/test_lib.erl | 9 +++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index 0071fb3dc1..cbe7179e0a 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.erl @@ -1130,7 +1130,7 @@ do_core_pp_1(M, A, Outdir) -> compile_forms(M, Core, [clint,ssalint,from_core,binary]), %% Don't optimize to test that we are not dependent - %% on the Core Erlang optmimization passes. + %% on the Core Erlang optimization passes. %% (Example of a previous bug: The core_parse pass %% would not turn map literals into #c_literal{} %% records; if sys_core_fold was run it would fix @@ -1154,7 +1154,16 @@ core_roundtrip(Config) -> ok = file:make_dir(Outdir), TestBeams = get_unique_beam_files(), - test_lib:p_run(fun(F) -> do_core_roundtrip(F, Outdir) end, TestBeams). + + Test = fun(F) -> do_core_roundtrip(F, Outdir) end, + case erlang:system_info(wordsize) of + 4 -> + %% This test case is very memory intensive. Only + %% use a single process. + test_lib:p_run(Test, TestBeams, 1); + 8 -> + test_lib:p_run(Test, TestBeams) + end. do_core_roundtrip(Beam, Outdir) -> try diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl index 0328ed9f26..c4d377e4f1 100644 --- a/lib/compiler/test/test_lib.erl +++ b/lib/compiler/test/test_lib.erl @@ -23,7 +23,7 @@ -compile({no_auto_import,[binary_part/2]}). -export([id/1,recompile/1,recompile_core/1,parallel/0, uniq/0,opt_opts/1,get_data_dir/1, - is_cloned_mod/1,smoke_disasm/1,p_run/2, + is_cloned_mod/1,smoke_disasm/1,p_run/2,p_run/3, highest_opcode/1]). %% Used by test case that override BIFs. @@ -139,6 +139,7 @@ is_cloned_mod(Mod) -> is_cloned_mod_1("_no_opt_SUITE") -> true; is_cloned_mod_1("_no_copt_SUITE") -> true; is_cloned_mod_1("_no_ssa_opt_SUITE") -> true; +is_cloned_mod_1("_no_type_opt_SUITE") -> true; is_cloned_mod_1("_post_opt_SUITE") -> true; is_cloned_mod_1("_inline_SUITE") -> true; is_cloned_mod_1("_no_module_opt_SUITE") -> true; @@ -166,7 +167,11 @@ p_run(Test, List) -> min(S0, 8) end, N = S + 1, - io:format("p_run: ~p parallel processes\n", [N]), + p_run(Test, List, N). + +p_run(Test, List, N) -> + io:format("p_run: ~p parallel processes; ~p jobs\n", + [N,length(List)]), p_run_loop(Test, List, N, [], 0, 0). p_run_loop(_, [], _, [], Errors, Ws) -> -- cgit v1.2.1 From 14af14649f08d5554484319e59ef77f4c4c5c674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 3 Nov 2022 10:03:09 +0100 Subject: Eliminate Dialyzer crash for ill-typed code Closes #6419 --- lib/dialyzer/src/dialyzer_dataflow.erl | 18 +++++++++++--- lib/dialyzer/src/dialyzer_typesig.erl | 29 ++++++++++++++-------- .../test/small_SUITE_data/results/bs_fail_constr | 4 +++ .../test/small_SUITE_data/src/bs_fail_constr.erl | 13 +++++++++- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl index 93142e8b1a..8e9b32434e 100644 --- a/lib/dialyzer/src/dialyzer_dataflow.erl +++ b/lib/dialyzer/src/dialyzer_dataflow.erl @@ -1599,7 +1599,8 @@ bind_bin_segs([Seg|Segs], BinType, Acc, Map, State) -> Val = cerl:bitstr_val(Seg), SegType = cerl:concrete(cerl:bitstr_type(Seg)), UnitVal = cerl:concrete(cerl:bitstr_unit(Seg)), - case cerl:bitstr_bitsize(Seg) of + Size = cerl:bitstr_size(Seg), + case bitstr_bitsize_type(Size) of all -> binary = SegType, [] = Segs, %% just an assert T = t_inf(t_bitstr(UnitVal, 0), BinType), @@ -1613,8 +1614,7 @@ bind_bin_segs([Seg|Segs], BinType, Acc, Map, State) -> Map, State, false, []), Type = t_binary(), bind_bin_segs(Segs, BinType, [Type|Acc], Map1, State); - BitSz when is_integer(BitSz); BitSz =:= any -> - Size = cerl:bitstr_size(Seg), + any -> {Map1, [SizeType]} = do_bind_pat_vars([Size], [t_non_neg_integer()], Map, State, false, []), Opaques = State#state.opaques, @@ -1665,6 +1665,18 @@ bind_bin_segs([Seg|Segs], BinType, Acc, Map, State) -> bind_bin_segs([], _BinType, Acc, Map, _State) -> {Map, lists:reverse(Acc)}. +bitstr_bitsize_type(Size) -> + case cerl:is_literal(Size) of + true -> + case cerl:concrete(Size) of + all -> all; + undefined -> utf; + _ -> any + end; + false -> + any + end. + %% Return the infimum (meet) of ExpectedType and Type if is not %% t_none(), and raise a bind_error() it is t_none(). bind_checked_inf(Pat, ExpectedType, Type, Opaques) -> diff --git a/lib/dialyzer/src/dialyzer_typesig.erl b/lib/dialyzer/src/dialyzer_typesig.erl index 342f11ad06..082dbdd521 100644 --- a/lib/dialyzer/src/dialyzer_typesig.erl +++ b/lib/dialyzer/src/dialyzer_typesig.erl @@ -255,17 +255,24 @@ traverse(Tree, DefinedVars, State) -> {State1, [SizeType, ValType]} = traverse_list([Size, Val], DefinedVars, State), {State2, TypeConstr, BinValTypeConstr} = - case cerl:bitstr_bitsize(Tree) of - all -> - T = t_bitstr(UnitVal, 0), - {State1, T, T}; - utf -> - %% contains an integer number of bytes - T = t_binary(), - {State1, T, T}; - N when is_integer(N) -> - {State1, t_bitstr(0, N), t_bitstr(1, N)}; - any -> % Size is not a literal + case cerl:is_literal(Size) of + true -> + case cerl:concrete(Size) of + all -> + T = t_bitstr(UnitVal, 0), + {State1, T, T}; + undefined -> %utf-8/16/32 + %% contains an integer number of bytes + T = t_binary(), + {State1, T, T}; + N0 when is_integer(N0) -> + N = N0 * UnitVal, + {State1, t_bitstr(0, N), t_bitstr(1, N)}; + _ -> + {State1, t_none(), t_none()} + end; + false -> + %% Size is not a literal T1 = ?mk_fun_var(bitstr_constr(SizeType, UnitVal), [SizeType]), T2 = ?mk_fun_var(bitstr_constr(SizeType, UnitVal, match), [SizeType]), diff --git a/lib/dialyzer/test/small_SUITE_data/results/bs_fail_constr b/lib/dialyzer/test/small_SUITE_data/results/bs_fail_constr index ce923a1c88..368c07a4e3 100644 --- a/lib/dialyzer/test/small_SUITE_data/results/bs_fail_constr +++ b/lib/dialyzer/test/small_SUITE_data/results/bs_fail_constr @@ -3,6 +3,10 @@ bs_fail_constr.erl:11:1: Function w3/1 has no local return bs_fail_constr.erl:12:8: Binary construction will fail since the size field S in segment 42:S has type neg_integer() bs_fail_constr.erl:14:1: Function w4/1 has no local return bs_fail_constr.erl:15:5: Binary construction will fail since the value field V in segment V/utf32 has type float() +bs_fail_constr.erl:18:1: Function bad_size_1/1 has no local return +bs_fail_constr.erl:18:1: The pattern <> can never match the type any() +bs_fail_constr.erl:21:1: Function bad_size_2/1 has no local return +bs_fail_constr.erl:24:9: The pattern <> can never match the type any() bs_fail_constr.erl:5:1: Function w1/1 has no local return bs_fail_constr.erl:6:5: Binary construction will fail since the value field V in segment V has type float() bs_fail_constr.erl:8:1: Function w2/1 has no local return diff --git a/lib/dialyzer/test/small_SUITE_data/src/bs_fail_constr.erl b/lib/dialyzer/test/small_SUITE_data/src/bs_fail_constr.erl index 8c1f8c009a..a687fb45d2 100644 --- a/lib/dialyzer/test/small_SUITE_data/src/bs_fail_constr.erl +++ b/lib/dialyzer/test/small_SUITE_data/src/bs_fail_constr.erl @@ -1,6 +1,6 @@ -module(bs_fail_constr). --export([w1/1, w2/1, w3/1, w4/1]). +-export([w1/1, w2/1, w3/1, w4/1, bad_size_1/1, bad_size_2/1]). w1(V) when is_float(V) -> <>. @@ -13,3 +13,14 @@ w3(S) when is_integer(S), S < 0 -> w4(V) when is_float(V) -> <>. + +%% GH-6419 +bad_size_1(<>) -> + ok. + +bad_size_2(Bin) -> + Size = [], + case Bin of + <> -> + ok + end. -- cgit v1.2.1 From 71136a9adf9a114297f82bad0140f0577cf2142a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Fri, 4 Nov 2022 10:06:34 +0100 Subject: compiler: Eliminate internal error in sub pass ssa_opt_bsm_shortcut Closes #6426 --- lib/compiler/src/beam_ssa_opt.erl | 7 ++++--- lib/compiler/test/bs_match_SUITE.erl | 9 +++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl index 4533b5b2ef..e10189afd8 100644 --- a/lib/compiler/src/beam_ssa_opt.erl +++ b/lib/compiler/src/beam_ssa_opt.erl @@ -1766,14 +1766,15 @@ coalesce_skips_is([#b_set{op=bs_match, args=[#b_literal{val=skip}, Ctx0,Type,Flags, #b_literal{val=Size0}, - #b_literal{val=Unit0}]}=Skip0, + #b_literal{val=Unit0}], + dst=Ctx}=Skip0, #b_set{op={succeeded,guard}}], #b_br{succ=L2,fail=Fail}=Br0, Bs0) when is_integer(Size0) -> case Bs0 of [{L2,#b_blk{is=[#b_set{op=bs_match, dst=SkipDst, - args=[#b_literal{val=skip},_,_,_, + args=[#b_literal{val=skip},Ctx,_,_, #b_literal{val=Size1}, #b_literal{val=Unit1}]}, #b_set{op={succeeded,guard}}=Succeeded], @@ -1787,7 +1788,7 @@ coalesce_skips_is([#b_set{op=bs_match, Is = [Skip,Succeeded], {Is,Br,Bs}; [{L2,#b_blk{is=[#b_set{op=bs_test_tail, - args=[_Ctx,#b_literal{val=TailSkip}]}], + args=[Ctx,#b_literal{val=TailSkip}]}], last=#b_br{succ=NextSucc,fail=Fail}}}|Bs] -> SkipBits = Size0 * Unit0, TestTail = Skip0#b_set{op=bs_test_tail, diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl index f5e33113ee..b477109f45 100644 --- a/lib/compiler/test/bs_match_SUITE.erl +++ b/lib/compiler/test/bs_match_SUITE.erl @@ -2448,6 +2448,11 @@ empty_matches(Config) when is_list(Config) -> <> = id(<<>>), 0 = id(Zero), + ok = em_4(<<>>, <<>>), + {'EXIT',{function_clause,[_|_]}} = catch em_4(<<>>, <<0:1>>), + {'EXIT',{function_clause,[_|_]}} = catch em_4(<<0:1>>, <<>>), + {'EXIT',{function_clause,[_|_]}} = catch em_4(<<0:1>>, <<0:1>>), + ok. em_1(Bytes) -> @@ -2471,6 +2476,10 @@ em_3(<>) -> em_3_1(I) -> I. +%% GH-6426/OTP-xxxxx +em_4(<>, <>) -> + ok. + %% beam_trim would sometimes crash when bs_start_match4 had {atom,resume} as %% its fail label. trim_bs_start_match_resume(Config) when is_list(Config) -> -- cgit v1.2.1