summaryrefslogtreecommitdiff
path: root/lib/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_validator.erl2
-rw-r--r--lib/compiler/src/sys_core_fold.erl28
-rw-r--r--lib/compiler/test/beam_validator_SUITE.erl19
-rw-r--r--lib/compiler/test/bif_SUITE.erl28
-rw-r--r--lib/compiler/test/core_fold_SUITE.erl20
5 files changed, 76 insertions, 21 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 98eacce0fc..b38d288f99 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -2299,6 +2299,8 @@ update_type(Merge, With, #value_ref{}=Ref, Vst0) ->
case Merge(Current, With) of
none ->
throw({type_conflict, Current, With});
+ Current ->
+ Vst0;
Type ->
Vst = update_container_type(Type, Ref, Vst0),
set_type(Type, Ref, Vst)
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index d79753068f..d96f3a6ae0 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -215,15 +215,15 @@ expr(#c_tuple{anno=Anno,es=Es0}=Tuple, Ctxt, Sub) ->
ann_c_tuple(Anno, Es)
end;
expr(#c_map{anno=Anno,arg=V0,es=Es0}=Map, Ctxt, Sub) ->
- Es = pair_list(Es0, Ctxt, descend(Map, Sub)),
+ %% Warn for useless building, but always build the map
+ %% anyway to preserve a possible exception.
case Ctxt of
- effect ->
- warn_useless_building(Map, Sub),
- make_effect_seq(Es, Sub);
- value ->
- V = expr(V0, Ctxt, Sub),
- ann_c_map(Anno,V,Es)
- end;
+ effect -> warn_useless_building(Map, Sub);
+ value -> ok
+ end,
+ Es = pair_list(Es0, descend(Map, Sub)),
+ V = expr(V0, value, Sub),
+ ann_c_map(Anno, V, Es);
expr(#c_binary{segments=Ss}=Bin0, Ctxt, Sub) ->
%% Warn for useless building, but always build the binary
%% anyway to preserve a possible exception.
@@ -490,14 +490,12 @@ ifes_list(_FVar, [], _Safe) ->
expr_list(Es, Ctxt, Sub) ->
[expr(E, Ctxt, Sub) || E <- Es].
-pair_list(Es, Ctxt, Sub) ->
- [pair(E, Ctxt, Sub) || E <- Es].
+pair_list(Es, Sub) ->
+ [pair(E, Sub) || E <- Es].
-pair(#c_map_pair{key=K,val=V}, effect, Sub) ->
- make_effect_seq([K,V], Sub);
-pair(#c_map_pair{key=K0,val=V0}=Pair, value=Ctxt, Sub) ->
- K = expr(K0, Ctxt, Sub),
- V = expr(V0, Ctxt, Sub),
+pair(#c_map_pair{key=K0,val=V0}=Pair, Sub) ->
+ K = expr(K0, value, Sub),
+ V = expr(V0, value, Sub),
Pair#c_map_pair{key=K,val=V}.
bitstr_list(Es, Sub) ->
diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl
index 64a356c7e4..aba3b8dfe2 100644
--- a/lib/compiler/test/beam_validator_SUITE.erl
+++ b/lib/compiler/test/beam_validator_SUITE.erl
@@ -41,7 +41,8 @@
missing_return_type/1,will_succeed/1,
bs_saved_position_units/1,parent_container/1,
container_performance/1,
- not_equal_inference/1]).
+ not_equal_inference/1,
+ inert_update_type/1]).
-include_lib("common_test/include/ct.hrl").
@@ -77,7 +78,8 @@ groups() ->
missing_return_type,will_succeed,
bs_saved_position_units,parent_container,
container_performance,
- not_equal_inference]}].
+ not_equal_inference,
+ inert_update_type]}].
init_per_suite(Config) ->
test_lib:recompile(?MODULE),
@@ -1045,5 +1047,18 @@ not_equal_inference(_Config) ->
not_equal_inference_1(X) when (X /= []) /= is_port(0 div 0) ->
[X || _ <- []].
+%% GH-6969: A type was made concrete even though that added no additional
+%% information.
+inert_update_type(_Config) ->
+ hello(<<"string">>, id(42)).
+
+hello(A, B) ->
+ mike([{sys_period, {A, B}}, {some_atom, B}]).
+
+mike([Head | _Rest]) -> joe(Head).
+
+joe({Name, 42}) -> Name;
+joe({sys_period, {A, _B}}) -> {41, 42, A}.
+
id(I) ->
I.
diff --git a/lib/compiler/test/bif_SUITE.erl b/lib/compiler/test/bif_SUITE.erl
index 8480569507..34bf54a871 100644
--- a/lib/compiler/test/bif_SUITE.erl
+++ b/lib/compiler/test/bif_SUITE.erl
@@ -24,7 +24,8 @@
-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,cover_safe_and_pure_bifs/1,
- cover_trim/1]).
+ cover_trim/1,
+ head_tail/1]).
suite() ->
[{ct_hooks,[ts_install_cth]}].
@@ -37,7 +38,8 @@ groups() ->
[beam_validator,
trunc_and_friends,
cover_safe_and_pure_bifs,
- cover_trim
+ cover_trim,
+ head_tail
]}].
init_per_suite(Config) ->
@@ -167,6 +169,28 @@ cover_trim_3(Header, N)->
false
end.
+%% GH-7024: The loader transformations for hd/1 and tl/1 were incorrect and
+%% failed when certain optimizations were turned off.
+head_tail(_Config) ->
+ {1, ok} = head_case(),
+ {1, ok} = tail_case(),
+
+ 1 = hd(id([1])),
+ [] = tl(id([1])),
+
+ ok.
+
+head_case() ->
+ case 1 of
+ X when hd(X) -> blurf;
+ X -> {X, ok}
+ end.
+
+tail_case() ->
+ case 1 of
+ X when tl(X) -> blurf;
+ X -> {X, ok}
+ end.
id(I) ->
I.
diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl
index 4da55bed2e..0bdcfab5b7 100644
--- a/lib/compiler/test/core_fold_SUITE.erl
+++ b/lib/compiler/test/core_fold_SUITE.erl
@@ -29,7 +29,7 @@
no_no_file/1,configuration/1,supplies/1,
redundant_stack_frame/1,export_from_case/1,
empty_values/1,cover_letrec_effect/1,
- receive_effect/1]).
+ receive_effect/1,map_effect/1]).
-export([foo/0,foo/1,foo/2,foo/3]).
@@ -50,7 +50,7 @@ groups() ->
no_no_file,configuration,supplies,
redundant_stack_frame,export_from_case,
empty_values,cover_letrec_effect,
- receive_effect]}].
+ receive_effect,map_effect]}].
init_per_suite(Config) ->
@@ -700,4 +700,20 @@ receive_effect(_Config) ->
do_receive_effect() ->
{} = receive _ -> {} = {} end.
+map_effect(_Config) ->
+ {'EXIT',{{badkey,key},_}} = catch map_effect_1(),
+
+ {'EXIT',{{badkey,key},_}} = catch map_effect_2(#{}),
+ {'EXIT',{{badmap,no_map},_}} = catch map_effect_2(no_map),
+
+ ok.
+
+map_effect_1() ->
+ #{}#{key := value},
+ ok.
+
+map_effect_2(Map) ->
+ Map#{key := value},
+ ok.
+
id(I) -> I.