diff options
Diffstat (limited to 'lib/compiler/test/guard_SUITE.erl')
-rw-r--r-- | lib/compiler/test/guard_SUITE.erl | 246 |
1 files changed, 234 insertions, 12 deletions
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl index 5f45eb3f68..1a96fa4b6c 100644 --- a/lib/compiler/test/guard_SUITE.erl +++ b/lib/compiler/test/guard_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2021. All Rights Reserved. +%% Copyright Ericsson AB 2001-2022. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,6 +19,10 @@ %% -module(guard_SUITE). +%% Warnings for obsolete guards are generated by erl_lint, so we will not +%% any less testing of the compiler by suppressing them. +-compile([nowarn_obsolete_guard]). + -include_lib("syntax_tools/include/merl.hrl"). -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, @@ -1254,8 +1258,30 @@ is_function_2(Config) when is_list(Config) -> F = fun(_) -> ok end, if - is_function(F, 1) -> ok - end. + is_function(F, 1) -> ok + end, + + variable_is_function_2(), + + ok. + +variable_is_function_2() -> + F = fun() -> ok end, + [F] = vif_1([id(F)], id(0), []), + [F] = vif_2([id(F)], id(0) band 15, []), + ok. + +%% Completely unknown arity +vif_1([F | Fs], Arity, Acc) when is_function(F, Arity) -> + vif_1(Fs, Arity, [F | Acc]); +vif_1([], _Arity, Acc) -> + Acc. + +%% Arity known to be between 0 and 15 +vif_2([F | Fs], Arity, Acc) when is_function(F, Arity) -> + vif_2(Fs, Arity, [F | Acc]); +vif_2([], _Arity, Acc) -> + Acc. tricky(Config) when is_list(Config) -> not_ok = tricky_1(1, 2), @@ -1409,23 +1435,37 @@ rel_op_combinations(Config) when is_list(Config) -> lists:seq(16#06F0, 16#06F9), Digits = gb_sets:from_list(Digits0), rel_op_combinations_1(16#0700, Digits), + false = is_digit(-1 bsl 59), + false = is_digit(-1 bsl 64), + false = is_digit((1 bsl 59) - 1), + false = is_digit(1 bsl 64), BrokenRange0 = lists:seq(3, 5) ++ lists:seq(10, 12) ++ lists:seq(14, 20), BrokenRange = gb_sets:from_list(BrokenRange0), rel_op_combinations_2(30, BrokenRange), + false = broken_range(-1 bsl 64), + false = broken_range(1 bsl 64), Red0 = [{I,2*I} || I <- lists:seq(0, 50)] ++ [{I,5*I} || I <- lists:seq(51, 80)], Red = gb_trees:from_orddict(Red0), rel_op_combinations_3(100, Red), + 2 * (-1 bsl 64) = redundant(-1 bsl 64), + none = redundant(1 bsl 64), + + rel_op_combinations_4(), - rel_op_combinations_4(). + rel_op_combinations_5(). rel_op_combinations_1(0, _) -> ok; rel_op_combinations_1(N, Digits) -> Bool = gb_sets:is_member(N, Digits), + Bool = is_digit(N), + rel_op_combinations_1(N-1, Digits). + +is_digit(N) -> Bool = is_digit_1(N), Bool = is_digit_2(N), Bool = is_digit_3(N), @@ -1436,8 +1476,7 @@ rel_op_combinations_1(N, Digits) -> Bool = is_digit_8(N), Bool = is_digit_9(42, N), Bool = is_digit_10(N, 0), - Bool = is_digit_11(N, 0), - rel_op_combinations_1(N-1, Digits). + Bool = is_digit_11(N, 0). is_digit_1(X) when 16#0660 =< X, X =< 16#0669 -> true; is_digit_1(X) when 16#0030 =< X, X =< 16#0039 -> true; @@ -1502,6 +1541,10 @@ rel_op_combinations_2(0, _) -> ok; rel_op_combinations_2(N, Range) -> Bool = gb_sets:is_member(N, Range), + Bool = broken_range(N), + rel_op_combinations_2(N-1, Range). + +broken_range(N) -> Bool = broken_range_1(N), Bool = broken_range_2(N), Bool = broken_range_3(N), @@ -1514,8 +1557,7 @@ rel_op_combinations_2(N, Range) -> Bool = broken_range_10(N), Bool = broken_range_11(N), Bool = broken_range_12(N), - Bool = broken_range_13(N), - rel_op_combinations_2(N-1, Range). + Bool = broken_range_13(N). broken_range_1(X) when X >= 10, X =< 20, X =/= 13 -> true; broken_range_1(X) when X >= 3, X =< 5 -> true; @@ -1587,6 +1629,10 @@ rel_op_combinations_3(N, Red) -> none -> none; {value,V} -> V end, + Val = redundant(N), + rel_op_combinations_3(N-1, Red). + +redundant(N) -> Val = redundant_1(N), Val = redundant_2(N), Val = redundant_3(N), @@ -1598,8 +1644,7 @@ rel_op_combinations_3(N, Red) -> Val = redundant_9(N), Val = redundant_10(N), Val = redundant_11(N), - Val = redundant_12(N), - rel_op_combinations_3(N-1, Red). + Val = redundant_12(N). redundant_1(X) when X >= 51, X =< 80 -> 5*X; redundant_1(X) when X < 51 -> 2*X; @@ -1673,6 +1718,145 @@ rel_op_vars_1(X, N) when X =< N -> le. rel_op_vars_2(X, N) when X =/= N -> ne; rel_op_vars_2(X, N) when X >= N -> ge. +rel_op_combinations_5() -> + lt = lt_gt_eq(a, b), + lt = lt_gt_eq(1.0, 42), + lt = lt_gt_eq(1, 42.0), + + eq = lt_gt_eq(a, a), + eq = lt_gt_eq(42, 42), + eq = lt_gt_eq(42.0, 42), + eq = lt_gt_eq(42, 42.0), + eq = lt_gt_eq(42.0, 42.0), + + gt = lt_gt_eq(b, a), + gt = lt_gt_eq(42.0, 1), + gt = lt_gt_eq(42, 1.0), + + lt = eq_exact_lt_gt(a, b), + lt = eq_exact_lt_gt(1.0, 42), + lt = eq_exact_lt_gt(1, 42.0), + + eq = eq_exact_lt_gt(a, a), + eq = eq_exact_lt_gt(42, 42), + none = eq_exact_lt_gt(42, 42.0), + + gt = eq_exact_lt_gt(b, a), + gt = eq_exact_lt_gt(42.0, 1), + gt = eq_exact_lt_gt(42, 1.0), + + ok. + +lt_gt_eq(A, B) -> + Res = lt_gt_eq_1(A, B), + Res = lt_gt_eq_2(A, B), + Res = lt_gt_eq_3(A, B), + Res = lt_gt_eq_4(A, B), + Res = lt_gt_eq_5(A, B), + lt_gt_eq_6(A, B). + +%% The last test in each 'if' is unnecessary. +lt_gt_eq_1(A, B) -> + if + A < B -> lt; + A == B -> eq; + A > B -> gt + end. + +lt_gt_eq_2(A, B) -> + if + A > B -> gt; + A == B -> eq; + A < B -> lt + end. + +lt_gt_eq_3(A, B) -> + if + A == B -> eq; + A < B -> lt; + A > B -> gt + end. + +lt_gt_eq_4(A, B) -> + if + A == B -> eq; + A > B -> gt; + A < B -> lt + end. + +lt_gt_eq_5(A, B) -> + if + A < B -> lt; + A > B -> gt; + A == B -> eq + end. + +lt_gt_eq_6(A, B) -> + if + A > B -> gt; + A < B -> lt; + A == B -> eq + end. + +eq_exact_lt_gt(A, B) -> + Res = eq_exact_lt_gt_1(A, B), + Res = eq_exact_lt_gt_2(A, B), + Res = eq_exact_lt_gt_3(A, B), + Res = eq_exact_lt_gt_4(A, B), + Res = eq_exact_lt_gt_5(A, B), + Res = eq_exact_lt_gt_6(A, B). + +%% Not possible to optimize (unless we have type information so we +%% know that A == B and A =:= B produces the same result). + +eq_exact_lt_gt_1(A, B) -> + if + A < B -> lt; + A =:= B -> eq; + A > B -> gt; + true -> none + end. + +eq_exact_lt_gt_2(A, B) -> + if + A > B -> gt; + A =:= B -> eq; + A < B -> lt; + true -> none + end. + +eq_exact_lt_gt_3(A, B) -> + if + A =:= B -> eq; + A < B -> lt; + A > B -> gt; + true -> none + end. + +eq_exact_lt_gt_4(A, B) -> + if + A =:= B -> eq; + A > B -> gt; + A < B -> lt; + true -> none + end. + +eq_exact_lt_gt_5(A, B) -> + if + A < B -> lt; + A > B -> gt; + A =:= B -> eq; + true -> none + end. + +eq_exact_lt_gt_6(A, B) -> + if + A > B -> gt; + A < B -> lt; + A =:= B -> eq; + true -> none + end. + %% Exhaustively test all combinations of relational operators %% to ensure the correctness of the optimizations in beam_ssa_dead. @@ -2362,6 +2546,9 @@ beam_bool_SUITE(_Config) -> erl1384(), gh4788(), beam_ssa_bool_coverage(), + bad_map_in_guard(), + gh_6164(), + gh_6184(), ok. before_and_inside_if() -> @@ -2873,6 +3060,42 @@ beam_ssa_bool_coverage_1(V) when V andalso 0, tuple_size(0) -> beam_ssa_bool_coverage_1(_) -> error. +gh_6164() -> + true = do_gh_6164(id([])), + {'EXIT',{{case_clause,42},_}} = catch do_gh_6164(id(0)), + + ok. + +do_gh_6164(V1) -> + case 42 of + V2 -> + case is_list(V1) of + V3 -> + case V3 orelse V2 of + _ when V3 -> 100 + end =< V3 + end + end. + +gh_6184() -> + {'EXIT',{function_clause,_}} = catch do_gh_6184(id(true), id({a,b,c})), + {'EXIT',{function_clause,_}} = catch do_gh_6184(true, true), + {'EXIT',{function_clause,_}} = catch do_gh_6184({a,b,c}, {x,y,z}), + + ok. + +do_gh_6184(V1, V2) when (false and is_tuple(V2)) andalso (V1 orelse V2) -> + V2 orelse V2. + +-record(bad_map_in_guard, {name}). +bad_map_in_guard() -> + error = bad_map_in_guard_1(). + +bad_map_in_guard_1() when (a#{key => value})#bad_map_in_guard.name -> + ok; +bad_map_in_guard_1() -> + error. + %%% %%% End of beam_bool_SUITE tests. %%% @@ -2925,5 +3148,4 @@ check(F, Result) -> ct:fail(check_failed) end. -fc({'EXIT',{function_clause,_}}) -> ok; -fc({'EXIT',{{case_clause,_},_}}) when ?MODULE =:= guard_inline_SUITE -> ok. +fc({'EXIT',{function_clause,_}}) -> ok. |