diff options
Diffstat (limited to 'lib/compiler/test')
-rw-r--r-- | lib/compiler/test/beam_block_SUITE.erl | 26 | ||||
-rw-r--r-- | lib/compiler/test/beam_utils_SUITE.erl | 6 | ||||
-rw-r--r-- | lib/compiler/test/bif_SUITE.erl | 20 | ||||
-rw-r--r-- | lib/compiler/test/bs_match_SUITE.erl | 48 | ||||
-rw-r--r-- | lib/compiler/test/core_fold_SUITE.erl | 20 | ||||
-rw-r--r-- | lib/compiler/test/float_SUITE.erl | 7 | ||||
-rw-r--r-- | lib/compiler/test/guard_SUITE.erl | 13 | ||||
-rw-r--r-- | lib/compiler/test/warnings_SUITE.erl | 1 |
8 files changed, 132 insertions, 9 deletions
diff --git a/lib/compiler/test/beam_block_SUITE.erl b/lib/compiler/test/beam_block_SUITE.erl index 9fcb6e497d..55d5f2dbe8 100644 --- a/lib/compiler/test/beam_block_SUITE.erl +++ b/lib/compiler/test/beam_block_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, get_map_elements/1,otp_7345/1,move_opt_across_gc_bif/1, - erl_202/1]). + erl_202/1,repro/1]). %% The only test for the following functions is that %% the code compiles and is accepted by beam_validator. @@ -39,7 +39,8 @@ groups() -> [get_map_elements, otp_7345, move_opt_across_gc_bif, - erl_202 + erl_202, + repro ]}]. init_per_suite(Config) -> @@ -158,6 +159,27 @@ erl_202({{_, _},X}, _) -> erl_202({_, _}, #erl_202_r1{y=R2}) -> {R2#erl_202_r2.x}. +%% See https://bugs.erlang.org/browse/ERL-266. +%% Instructions with failure labels are not safe to include +%% in a block. Including get_map_elements in a block would +%% lead to unsafe code. + +repro(_Config) -> + [] = maps:to_list(repro([], #{}, #{})), + [{tmp1,n}] = maps:to_list(repro([{tmp1,0}], #{}, #{})), + [{tmp1,name}] = maps:to_list(repro([{tmp1,0}], #{}, #{0=>name})), + ok. + +repro([], TempNames, _Slots) -> + TempNames; +repro([{Temp, Slot}|Xs], TempNames, Slots0) -> + {Name, Slots} = + case Slots0 of + #{Slot := Name0} -> {Name0, Slots0}; + #{} -> {n, Slots0#{Slot => n}} + end, + repro(Xs, TempNames#{Temp => Name}, Slots). + %%% %%% The only test of the following code is that it compiles. %%% diff --git a/lib/compiler/test/beam_utils_SUITE.erl b/lib/compiler/test/beam_utils_SUITE.erl index f6d4a311bb..5e29f8d7b4 100644 --- a/lib/compiler/test/beam_utils_SUITE.erl +++ b/lib/compiler/test/beam_utils_SUITE.erl @@ -283,6 +283,9 @@ coverage(_Config) -> {'EXIT',{function_clause,_}} = (catch town(overall, {{abc},alcohol})), + self() ! junk_message, + {"url",#{true:="url"}} = appointment(#{"resolution" => "url"}), + ok. %% Cover check_liveness/3. @@ -352,6 +355,9 @@ yellow(Hill) -> Hill, id(42). +do(A, B) -> {A,B}. +appointment(#{"resolution" := Url}) -> + do(receive _ -> Url end, #{true => Url}). %% The identity function. id(I) -> I. diff --git a/lib/compiler/test/bif_SUITE.erl b/lib/compiler/test/bif_SUITE.erl index 6bde2f1da9..bba2058f2f 100644 --- a/lib/compiler/test/bif_SUITE.erl +++ b/lib/compiler/test/bif_SUITE.erl @@ -23,7 +23,7 @@ -export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1, init_per_group/2,end_per_group/2, - beam_validator/1,trunc_and_friends/1]). + beam_validator/1,trunc_and_friends/1,cover_safe_bifs/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. @@ -35,7 +35,8 @@ all() -> groups() -> [{p,[parallel], [beam_validator, - trunc_and_friends + trunc_and_friends, + cover_safe_bifs ]}]. init_per_suite(Config) -> @@ -104,3 +105,18 @@ trunc_template(Func, Bif) -> try begin _@Bif@(a), ok end catch error:badarg -> ok end, ok."). + +cover_safe_bifs(Config) -> + _ = get(), + _ = get_keys(a), + _ = group_leader(), + _ = is_alive(), + _ = min(Config, []), + _ = nodes(), + _ = erlang:ports(), + _ = pre_loaded(), + _ = processes(), + _ = registered(), + _ = term_to_binary(Config), + + ok. diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl index 224abf6c29..6742571b86 100644 --- a/lib/compiler/test/bs_match_SUITE.erl +++ b/lib/compiler/test/bs_match_SUITE.erl @@ -38,7 +38,8 @@ no_partition/1,calling_a_binary/1,binary_in_map/1, match_string_opt/1,select_on_integer/1, map_and_binary/1,unsafe_branch_caching/1, - bad_literals/1,good_literals/1,constant_propagation/1]). + bad_literals/1,good_literals/1,constant_propagation/1, + parse_xml/1]). -export([coverage_id/1,coverage_external_ignore/2]). @@ -69,7 +70,7 @@ groups() -> no_partition,calling_a_binary,binary_in_map, match_string_opt,select_on_integer, map_and_binary,unsafe_branch_caching, - bad_literals,good_literals,constant_propagation]}]. + bad_literals,good_literals,constant_propagation,parse_xml]}]. init_per_suite(Config) -> @@ -768,6 +769,11 @@ multiple_uses(Config) when is_list(Config) -> {344,62879,345,<<245,159,1,89>>} = multiple_uses_1(<<1,88,245,159,1,89>>), true = multiple_uses_2(<<0,0,197,18>>), <<42,43>> = multiple_uses_3(<<0,0,42,43>>, fun id/1), + + ok = first_after(<<>>, 42), + <<1>> = first_after(<<1,2,3>>, 0), + <<2>> = first_after(<<1,2,3>>, 1), + ok. multiple_uses_1(<<X:16,Tail/binary>>) -> @@ -789,6 +795,24 @@ multiple_uses_match(<<Y:16,Z:16>>) -> multiple_uses_cmp(<<Y:16>>, <<Y:16>>) -> true; multiple_uses_cmp(<<_:16>>, <<_:16>>) -> false. +first_after(Data, Offset) -> + case byte_size(Data) > Offset of + false -> + {First, Rest} = {ok, ok}, + ok; + true -> + <<_:Offset/binary, Rest/binary>> = Data, + %% 'Rest' saved in y(0) before the call. + {First, _} = match_first(Data, Rest), + %% When beam_bsm sees the code, the following line + %% which uses y(0) has been optimized away. + {First, Rest} = {First, Rest}, + First + end. + +match_first(_, <<First:1/binary, Rest/binary>>) -> + {First, Rest}. + zero_label(Config) when is_list(Config) -> <<"nosemouth">> = read_pols(<<"FACE","nose","mouth">>), <<"CE">> = read_pols(<<"noFACE">>), @@ -1451,6 +1475,26 @@ constant_propagation_c() -> X end. +parse_xml(_Config) -> + <<"<?xmlX">> = do_parse_xml(<<"<?xmlX">>), + <<" ">> = do_parse_xml(<<"<?xml ">>), + ok. + +do_parse_xml(<<"<?xml"/utf8,Rest/binary>> = Bytes) -> + %% Delayed sub-binary creation is not safe. A buggy (development) + %% version of check_liveness_everywhere() in beam_utils would turn + %% on the optimization. + Rest1 = case is_next_char_whitespace(Rest) of + false -> + Bytes; + true -> + id(Rest) + end, + id(Rest1). + +is_next_char_whitespace(<<C/utf8,_/binary>>) -> + C =:= $\s. + check(F, R) -> R = F(). diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl index ced0e39d06..0097e28d4d 100644 --- a/lib/compiler/test/core_fold_SUITE.erl +++ b/lib/compiler/test/core_fold_SUITE.erl @@ -26,7 +26,7 @@ unused_multiple_values_error/1,unused_multiple_values/1, multiple_aliases/1,redundant_boolean_clauses/1, mixed_matching_clauses/1,unnecessary_building/1, - no_no_file/1,configuration/1]). + no_no_file/1,configuration/1,supplies/1]). -export([foo/0,foo/1,foo/2,foo/3]). @@ -45,7 +45,7 @@ groups() -> unused_multiple_values_error,unused_multiple_values, multiple_aliases,redundant_boolean_clauses, mixed_matching_clauses,unnecessary_building, - no_no_file,configuration]}]. + no_no_file,configuration,supplies]}]. init_per_suite(Config) -> @@ -511,4 +511,20 @@ configuration() -> art() -> creating. +%% core_lint would complain after optimization. A call to error/1 +%% must not occur unconditionally in a guard. +supplies(_Config) -> + case ?MODULE of + core_fold_inline_SUITE -> + %% Other error behaviour when inlined. + ok; + _ -> + {'EXIT',{function_clause,_}} = (catch do_supplies(#{1 => <<1,2,3>>})), + {'EXIT',{function_clause,_}} = (catch do_supplies(#{1 => a})), + {'EXIT',{function_clause,_}} = (catch do_supplies(42)), + ok + end. + +do_supplies(#{1 := Value}) when byte_size(Value), byte_size(kg) -> working. + id(I) -> I. diff --git a/lib/compiler/test/float_SUITE.erl b/lib/compiler/test/float_SUITE.erl index 0ebc71eb9b..08c3dd8593 100644 --- a/lib/compiler/test/float_SUITE.erl +++ b/lib/compiler/test/float_SUITE.erl @@ -155,6 +155,13 @@ math_functions(Config) when is_list(Config) -> 5.0 = math:floor(id(5.4)), 6.0 = math:ceil(id(5.4)), + 0.0 = math:fmod(42, 42), + 0.25 = math:fmod(1, 0.75), + -1.0 = math:fmod(-4.0, 1.5), + -0.375 = math:fmod(-3.0, -0.875), + 0.125 = math:fmod(8.125, -4), + {'EXIT',{badarith,_}} = (catch math:fmod(5.0, 0.0)), + %% Only for coverage (of beam_type.erl). {'EXIT',{undef,_}} = (catch math:fnurfla(0)), {'EXIT',{undef,_}} = (catch math:fnurfla(0, 0)), diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl index 6302f82f29..429d6b79e0 100644 --- a/lib/compiler/test/guard_SUITE.erl +++ b/lib/compiler/test/guard_SUITE.erl @@ -87,6 +87,7 @@ misc(Config) when is_list(Config) -> {ok,buf,<<>>} = get_data({o,true,0}, 42, buf), {ok,buf,<<>>} = get_data({o,false,0}, 0, buf), error = get_data({o,false,0}, 42, buf), + ok. @@ -343,6 +344,11 @@ complex_semicolon(Config) when is_list(Config) -> ok = csemi7(#{a=>1}, 3, 3), ok = csemi7(#{a=>1, b=>3}, 0, 0), + %% 8: Make sure that funs cannot be copied into guards. + ok = csemi8(true), + error = csemi8(false), + error = csemi8(42), + ok. csemi1(Type, Val) when is_list(Val), Type == float; @@ -457,6 +463,13 @@ csemi6(_, _) -> error. csemi7(A, B, C) when A#{a:=B} > #{a=>1}; abs(C) > 2 -> ok; csemi7(_, _, _) -> error. +csemi8(Together) -> + case fun csemi8/1 of + Typically when Together; Typically, Together -> ok; + _ -> error + end. + + comma(Config) when is_list(Config) -> %% ',' combinations of literal true/false. diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl index f884e6e7d6..35f7db82bd 100644 --- a/lib/compiler/test/warnings_SUITE.erl +++ b/lib/compiler/test/warnings_SUITE.erl @@ -281,7 +281,6 @@ bad_arith(Config) when is_list(Config) -> {3,sys_core_fold,{eval_failure,badarith}}, {9,sys_core_fold,nomatch_guard}, {9,sys_core_fold,{eval_failure,badarith}}, - {9,sys_core_fold,{no_effect,{erlang,is_integer,1}}}, {10,sys_core_fold,nomatch_guard}, {10,sys_core_fold,{eval_failure,badarith}}, {15,sys_core_fold,{eval_failure,badarith}} |