aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler/test')
-rw-r--r--lib/compiler/test/Makefile1
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl15
-rw-r--r--lib/compiler/test/core_SUITE.erl5
-rw-r--r--lib/compiler/test/core_SUITE_data/eval_case.core34
-rw-r--r--lib/compiler/test/core_fold_SUITE.erl36
-rw-r--r--lib/compiler/test/map_SUITE.erl51
-rw-r--r--lib/compiler/test/warnings_SUITE.erl9
7 files changed, 136 insertions, 15 deletions
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index 0a637a07cd..39c9fea5d9 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -48,6 +48,7 @@ NO_OPT= \
fun \
guard \
lc \
+ map \
match \
misc \
num_bif \
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 9f15845d33..149b9bbb8f 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -34,7 +34,7 @@
otp_7188/1,otp_7233/1,otp_7240/1,otp_7498/1,
match_string/1,zero_width/1,bad_size/1,haystack/1,
cover_beam_bool/1,matched_out_size/1,follow_fail_branch/1,
- no_partition/1]).
+ no_partition/1,calling_a_binary/1]).
-export([coverage_id/1,coverage_external_ignore/2]).
@@ -59,7 +59,7 @@ groups() ->
matching_and_andalso,otp_7188,otp_7233,otp_7240,
otp_7498,match_string,zero_width,bad_size,haystack,
cover_beam_bool,matched_out_size,follow_fail_branch,
- no_partition]}].
+ no_partition,calling_a_binary]}].
init_per_suite(Config) ->
@@ -1178,6 +1178,17 @@ no_partition_2([], a5) ->
no_partition_2(42.0, a6) ->
six.
+calling_a_binary(Config) when is_list(Config) ->
+ [] = call_binary(<<>>, []),
+ {'EXIT',{badarg,_}} = (catch call_binary(<<1>>, [])),
+ {'EXIT',{badarg,_}} = (catch call_binary(<<1,2,3>>, [])),
+ ok.
+
+call_binary(<<>>, Acc) ->
+ Acc;
+call_binary(<<H,T/bits>>, Acc) ->
+ T(<<Acc/binary,H>>).
+
check(F, R) ->
R = F().
diff --git a/lib/compiler/test/core_SUITE.erl b/lib/compiler/test/core_SUITE.erl
index 1a521c3591..aa222c48de 100644
--- a/lib/compiler/test/core_SUITE.erl
+++ b/lib/compiler/test/core_SUITE.erl
@@ -24,7 +24,7 @@
dehydrated_itracer/1,nested_tries/1,
seq_in_guard/1,make_effect_seq/1,eval_is_boolean/1,
unsafe_case/1,nomatch_shadow/1,reversed_annos/1,
- map_core_test/1]).
+ map_core_test/1,eval_case/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -50,7 +50,7 @@ groups() ->
[{p,test_lib:parallel(),
[dehydrated_itracer,nested_tries,seq_in_guard,make_effect_seq,
eval_is_boolean,unsafe_case,nomatch_shadow,reversed_annos,
- map_core_test
+ map_core_test,eval_case
]}].
@@ -76,6 +76,7 @@ end_per_group(_GroupName, Config) ->
?comp(nomatch_shadow).
?comp(reversed_annos).
?comp(map_core_test).
+?comp(eval_case).
try_it(Mod, Conf) ->
Src = filename:join(?config(data_dir, Conf), atom_to_list(Mod)),
diff --git a/lib/compiler/test/core_SUITE_data/eval_case.core b/lib/compiler/test/core_SUITE_data/eval_case.core
new file mode 100644
index 0000000000..f2776e2b1f
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/eval_case.core
@@ -0,0 +1,34 @@
+module 'eval_case' ['eval_case'/0]
+ attributes []
+'eval_case'/0 =
+ fun () ->
+ case <> of
+ <> when 'true' ->
+ case apply 'do_case'/0() of
+ <'ok'> when 'true' ->
+ 'ok'
+ ( <_cor0> when 'true' ->
+ primop 'match_fail'
+ ({'badmatch',_cor0})
+ -| ['compiler_generated'] )
+ end
+ ( <> when 'true' ->
+ ( primop 'match_fail'
+ ({'function_clause'})
+ -| [{'function_name',{'eval_case',0}}] )
+ -| ['compiler_generated'] )
+ end
+'do_case'/0 =
+ fun () ->
+ case let <_cor0> =
+ apply 'id'/1(42)
+ in let <_cor1> =
+ call 'erlang':'+'
+ (_cor0, 7)
+ in {'x',_cor1} of
+ <{'x',49}> when 'true' ->
+ 'ok'
+ end
+'id'/1 =
+ fun (_cor0) -> _cor0
+end
diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl
index 69f61a046f..8151dc1b16 100644
--- a/lib/compiler/test/core_fold_SUITE.erl
+++ b/lib/compiler/test/core_fold_SUITE.erl
@@ -22,7 +22,8 @@
init_per_group/2,end_per_group/2,
t_element/1,setelement/1,t_length/1,append/1,t_apply/1,bifs/1,
eq/1,nested_call_in_case/1,guard_try_catch/1,coverage/1,
- unused_multiple_values_error/1,unused_multiple_values/1]).
+ unused_multiple_values_error/1,unused_multiple_values/1,
+ multiple_aliases/1]).
-export([foo/0,foo/1,foo/2,foo/3]).
@@ -38,7 +39,8 @@ groups() ->
[{p,test_lib:parallel(),
[t_element,setelement,t_length,append,t_apply,bifs,
eq,nested_call_in_case,guard_try_catch,coverage,
- unused_multiple_values_error,unused_multiple_values]}].
+ unused_multiple_values_error,unused_multiple_values,
+ multiple_aliases]}].
init_per_suite(Config) ->
@@ -299,8 +301,6 @@ cover_is_safe_bool_expr(X) ->
bsm_an_inlined(<<_:8>>, _) -> ok;
bsm_an_inlined(_, _) -> error.
-id(I) -> I.
-
unused_multiple_values_error(Config) when is_list(Config) ->
PrivDir = ?config(priv_dir, Config),
Dir = filename:dirname(code:which(?MODULE)),
@@ -338,3 +338,31 @@ do_something(I) ->
put(unused_multiple_values,
[I|get(unused_multiple_values)]),
I.
+
+
+%% Make sure that multiple aliases does not cause
+%% the case expression to be evaluated twice.
+multiple_aliases(Config) when is_list(Config) ->
+ do_ma(fun() ->
+ X = Y = run_once(),
+ {X,Y}
+ end, {ok,ok}),
+ do_ma(fun() ->
+ case {true,run_once()} of
+ {true=A=B,ok=X=Y} ->
+ {A,B,X,Y}
+ end
+ end, {true,true,ok,ok}),
+ ok.
+
+do_ma(Fun, Expected) when is_function(Fun, 0) ->
+ Expected = Fun(),
+ ran_once = erase(run_once),
+ ok.
+
+run_once() ->
+ undefined = put(run_once, ran_once),
+ ok.
+
+
+id(I) -> I.
diff --git a/lib/compiler/test/map_SUITE.erl b/lib/compiler/test/map_SUITE.erl
index 0ba5d5dd0d..86f65c3ed6 100644
--- a/lib/compiler/test/map_SUITE.erl
+++ b/lib/compiler/test/map_SUITE.erl
@@ -38,10 +38,10 @@
%% not covered in 17.0-rc1
t_build_and_match_over_alloc/1,
t_build_and_match_empty_val/1,
- t_build_and_match_val/1
+ t_build_and_match_val/1,
%% errors in 17.0-rc1
-
+ t_update_values/1
]).
suite() -> [].
@@ -62,10 +62,10 @@ all() -> [
%% not covered in 17.0-rc1
t_build_and_match_over_alloc,
t_build_and_match_empty_val,
- t_build_and_match_val
+ t_build_and_match_val,
%% errors in 17.0-rc1
-
+ t_update_values
].
groups() -> [].
@@ -179,6 +179,17 @@ t_update_map_expressions(Config) when is_list(Config) ->
#{ a :=42, b:=42, c:=42 } = (maps:from_list([{a,1},{b,2},{c,3}]))#{ a := 42, b := 42, c := 42 },
#{ "a" :=1, "b":=42, "c":=42 } = (maps:from_list([{"a",1},{"b",2}]))#{ "b" := 42, "c" => 42 },
+ %% Test need to be in a fun.
+ %% This tests that let expr optimisation in sys_core_fold
+ %% covers maps correctly.
+ F = fun() ->
+ M0 = id(#{ "a" => [1,2,3] }),
+ #{ "a" := _ } = M0,
+ M0#{ "a" := b }
+ end,
+
+ #{ "a" := b } = F(),
+
%% Error cases, FIXME: should be 'badmap'?
{'EXIT',{badarg,_}} = (catch (id(<<>>))#{ a := 42, b => 2 }),
{'EXIT',{badarg,_}} = (catch (id([]))#{ a := 42, b => 2 }),
@@ -212,16 +223,46 @@ t_update_exact(Config) when is_list(Config) ->
M2 = M0#{3.0:=new},
#{1:=a,2:=b,3.0:=new,4:=d,5:=e} = M2,
M2 = M0#{3.0=>wrong,3.0:=new},
- M2 = M0#{3=>wrong,3.0:=new},
+ true = M2 =/= M0#{3=>right,3.0:=new},
+ #{ 3 := right, 3.0 := new } = M0#{3=>right,3.0:=new},
+
+ M3 = id(#{ 1 => val}),
+ #{1 := update2,1.0 := new_val4} = M3#{
+ 1.0 => new_val1, 1 := update, 1=> update3,
+ 1 := update2, 1.0 := new_val2, 1.0 => new_val3,
+ 1.0 => new_val4 },
%% Errors cases.
+ {'EXIT',{badarg,_}} = (catch ((id(nil))#{ a := b })),
{'EXIT',{badarg,_}} = (catch M0#{nonexisting:=val}),
{'EXIT',{badarg,_}} = (catch M0#{1.0:=v,1.0=>v2}),
{'EXIT',{badarg,_}} = (catch M0#{42.0:=v,42:=v2}),
{'EXIT',{badarg,_}} = (catch M0#{42=>v1,42.0:=v2,42:=v3}),
+ ok.
+t_update_values(Config) when is_list(Config) ->
+ V0 = id(1337),
+ M0 = #{ a => 1, val => V0},
+ V1 = get_val(M0),
+ M1 = M0#{ val := [V0,V1], "wazzup" => 42 },
+ [1337, {some_val, 1337}] = get_val(M1),
+
+ N = 110,
+ List = [{[I,1,2,3,I],{1,2,3,"wat",I}}|| I <- lists:seq(1,N)],
+
+ {_,_,#{val2 := {1,2,3,"wat",N}, val1 := [N,1,2,3,N]}} = lists:foldl(fun
+ ({V2,V3},{Old2,Old3,Mi}) ->
+ ok = check_val(Mi,Old2,Old3),
+ #{ val1 := Old2, val2 := Old3 } = Mi,
+ {V2,V3, Mi#{ val1 := id(V2), val2 := V1, val2 => id(V3)}}
+ end, {none, none, #{val1=>none,val2=>none}},List),
ok.
+check_val(#{val1:=V1, val2:=V2},V1,V2) -> ok.
+
+get_val(#{ "wazzup" := _, val := V}) -> V;
+get_val(#{ val := V }) -> {some_val, V}.
+
t_guard_bifs(Config) when is_list(Config) ->
true = map_guard_head(#{a=>1}),
false = map_guard_head([]),
diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl
index 7186956603..16d15a59e5 100644
--- a/lib/compiler/test/warnings_SUITE.erl
+++ b/lib/compiler/test/warnings_SUITE.erl
@@ -390,6 +390,10 @@ effect(Config) when is_list(Config) ->
<<X:8>>;
unused_fun ->
fun() -> {ok,X} end;
+ unused_named_fun ->
+ fun F(0) -> 1;
+ F(N) -> N*F(N-1)
+ end;
unused_atom ->
ignore; %no warning
unused_nil ->
@@ -484,8 +488,9 @@ effect(Config) when is_list(Config) ->
{22,sys_core_fold,{no_effect,{erlang,is_integer,1}}},
{24,sys_core_fold,useless_building},
{26,sys_core_fold,useless_building},
- {32,sys_core_fold,{no_effect,{erlang,'=:=',2}}},
- {34,sys_core_fold,{no_effect,{erlang,get_cookie,0}}}]}}],
+ {28,sys_core_fold,useless_building},
+ {36,sys_core_fold,{no_effect,{erlang,'=:=',2}}},
+ {38,sys_core_fold,{no_effect,{erlang,get_cookie,0}}}]}}],
?line [] = run(Config, Ts),
ok.