diff options
author | Björn Gustavsson <[email protected]> | 2019-05-20 11:54:22 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2019-05-20 13:22:55 +0200 |
commit | cabdef3b97c077119fe6f43538dbdd5cffe9dd91 (patch) | |
tree | 87a6fe405f4d1d6f7f4e0f0db3ea4dd34688e9bb /lib/compiler/src | |
parent | 6618ce7b6a621e92db72ea4f01f7d38553c8818c (diff) | |
download | otp-cabdef3b97c077119fe6f43538dbdd5cffe9dd91.tar.gz otp-cabdef3b97c077119fe6f43538dbdd5cffe9dd91.tar.bz2 otp-cabdef3b97c077119fe6f43538dbdd5cffe9dd91.zip |
Fix non-terminating compilation
The compiler would not terminate while compiling the following code:
foo(<<N:32>>, Tuple, NewValue) ->
_ = element(N, Tuple),
setelement(N, Tuple, NewValue).
The type analysis pass would attempt to construct a huge list when
attempting analyse the type of `Tuple` after the call to
`setelement/3`.
https://bugs.erlang.org/browse/ERL-948
Diffstat (limited to 'lib/compiler/src')
-rw-r--r-- | lib/compiler/src/beam_ssa_type.erl | 16 |
1 files changed, 11 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}. |