aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2019-05-29 13:24:41 +0200
committerErlang/OTP <[email protected]>2019-05-29 13:24:41 +0200
commit787a7684b02a01818eb99abc0f6a168250e192a9 (patch)
treef4a81eb55f1df223696c7792c28ef2a4e2942108 /lib
parentb6d769e80f9b0be730896e0a7a655d7b7344368b (diff)
parentcabdef3b97c077119fe6f43538dbdd5cffe9dd91 (diff)
downloadotp-787a7684b02a01818eb99abc0f6a168250e192a9.tar.gz
otp-787a7684b02a01818eb99abc0f6a168250e192a9.tar.bz2
otp-787a7684b02a01818eb99abc0f6a168250e192a9.zip
Merge branch 'bjorn/compiler/fix-freeze/ERL-948/OTP-15828' into maint-22
* bjorn/compiler/fix-freeze/ERL-948/OTP-15828: Fix non-terminating compilation
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/beam_ssa_type.erl16
-rw-r--r--lib/compiler/test/beam_type_SUITE.erl14
2 files changed, 25 insertions, 5 deletions
diff --git a/lib/compiler/src/beam_ssa_type.erl b/lib/compiler/src/beam_ssa_type.erl
index 06b42f1928..2ea7e89dfa 100644
--- a/lib/compiler/src/beam_ssa_type.erl
+++ b/lib/compiler/src/beam_ssa_type.erl
@@ -24,7 +24,7 @@
-include("beam_ssa_opt.hrl").
-import(lists, [all/2,any/2,droplast/1,foldl/3,last/1,member/2,
keyfind/3,partition/2,reverse/1,reverse/2,
- seq/2,sort/1,split/2]).
+ sort/1,split/2]).
-define(UNICODE_INT, #t_integer{elements={0,16#10FFFF}}).
@@ -874,11 +874,11 @@ type(call, [#b_remote{mod=#b_literal{val=Mod},
true ->
none
end;
- {#t_integer{elements={Min,Max}},
+ {#t_integer{elements={Min,_}}=IntType,
#t_tuple{elements=Es0,size=Size}=T} ->
- %% We know this will land between Min and Max, so kill the
- %% types for those indexes.
- Es = maps:without(seq(Min, Max), Es0),
+ %% Remove type information for all indices that
+ %% falls into the range of the integer.
+ Es = remove_element_info(IntType, Es0),
case T#t_tuple.exact of
false ->
T#t_tuple{elements=Es,size=max(Min, Size)};
@@ -1649,6 +1649,12 @@ get_literal_from_type(nil) ->
#b_literal{val=[]};
get_literal_from_type(_) -> none.
+remove_element_info(#t_integer{elements={Min,Max}}, Es) ->
+ foldl(fun(El, Acc) when Min =< El, El =< Max ->
+ maps:remove(El, Acc);
+ (_El, Acc) -> Acc
+ end, Es, maps:keys(Es)).
+
t_atom() ->
#t_atom{elements=any}.
diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl
index 882e281a44..0d1680fb15 100644
--- a/lib/compiler/test/beam_type_SUITE.erl
+++ b/lib/compiler/test/beam_type_SUITE.erl
@@ -271,8 +271,22 @@ setelement(_Config) ->
T0 = id({a,42}),
{a,_} = T0,
{b,_} = setelement(1, T0, b),
+ {z,b} = do_setelement_1(<<(id(1)):32>>, {a,b}, z),
+ {new,two} = do_setelement_2(<<(id(1)):1>>, {one,two}, new),
ok.
+do_setelement_1(<<N:32>>, Tuple, NewValue) ->
+ _ = element(N, Tuple),
+ %% While updating the type for Tuple, beam_ssa_type would do:
+ %% maps:without(lists:seq(0, 4294967295), Elements)
+ setelement(N, Tuple, NewValue).
+
+do_setelement_2(<<N:1>>, Tuple, NewValue) ->
+ %% Cover the second clause in remove_element_info/2. The
+ %% type for the second element will be kept.
+ two = element(2, Tuple),
+ setelement(N, Tuple, NewValue).
+
cons(_Config) ->
[did] = cons(assigned, did),