diff options
author | Björn Gustavsson <[email protected]> | 2018-01-31 10:17:53 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2018-01-31 10:17:53 +0100 |
commit | 2208953ca144858ddc343721a9cc40e43cc7fe0c (patch) | |
tree | 417bda1a7c739bf8a6dfa1df1cf486ae75d99dae /lib/compiler | |
parent | 1fe1c9a57d365c8203cb1380e4bdfe8f7f6ab8ce (diff) | |
parent | 2e5063371ca21eeabd9c20462c16fac0ee147028 (diff) | |
download | otp-2208953ca144858ddc343721a9cc40e43cc7fe0c.tar.gz otp-2208953ca144858ddc343721a9cc40e43cc7fe0c.tar.bz2 otp-2208953ca144858ddc343721a9cc40e43cc7fe0c.zip |
Merge branch 'maint'
* maint:
Fix incorrect type interference of integer ranges
Conflicts:
lib/compiler/src/beam_type.erl
Diffstat (limited to 'lib/compiler')
-rw-r--r-- | lib/compiler/src/beam_type.erl | 8 | ||||
-rw-r--r-- | lib/compiler/test/beam_type_SUITE.erl | 33 |
2 files changed, 37 insertions, 4 deletions
diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl index b2fabed2c5..a2e3af37d0 100644 --- a/lib/compiler/src/beam_type.erl +++ b/lib/compiler/src/beam_type.erl @@ -943,10 +943,10 @@ merge_type_info({tuple,SzKind1,Sz1,[]}, {tuple,_SzKind2,_Sz2,First}=Tuple2) -> merge_type_info({tuple,SzKind1,Sz1,First}, Tuple2); merge_type_info({tuple,_SzKind1,_Sz1,First}=Tuple1, {tuple,SzKind2,Sz2,_}) -> merge_type_info(Tuple1, {tuple,SzKind2,Sz2,First}); -merge_type_info(integer, {integer,_}=Int) -> - Int; -merge_type_info({integer,_}=Int, integer) -> - Int; +merge_type_info(integer, {integer,_}) -> + integer; +merge_type_info({integer,_}, integer) -> + integer; merge_type_info({integer,{Min1,Max1}}, {integer,{Min2,Max2}}) -> {integer,{max(Min1, Min2),min(Max1, Max2)}}; merge_type_info({binary,U1}, {binary,U2}) -> diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl index dfbf2aa4a0..e33df809ff 100644 --- a/lib/compiler/test/beam_type_SUITE.erl +++ b/lib/compiler/test/beam_type_SUITE.erl @@ -67,6 +67,15 @@ integers(_Config) -> college = do_integers_3(), + zero = do_integers_4(<<0:1>>, 0), + one = do_integers_4(<<1:1>>, 0), + other = do_integers_4(<<1:1>>, 2), + + zero = do_integers_5(0, 0), + one = do_integers_5(0, 1), + two = do_integers_5(0, 2), + three = do_integers_5(0, 3), + ok. do_integers_1(B0) -> @@ -89,6 +98,30 @@ do_integers_3() -> 1 -> 0 end. +do_integers_4(<<X:1,T/bits>>, C) -> + %% Binary matching gives the range 0-1 for X. + %% The range for `X bor C` is unknown. It must not be inherited + %% from X. (`X bor C` will reuse the register used for X.) + case X bor C of + 0 -> do_integers_4(T, C, zero); + 1 -> do_integers_4(T, C, one); + _ -> do_integers_4(T, C, other) + end. + +do_integers_4(_, _, Res) -> + Res. + +do_integers_5(X0, Y0) -> + %% X and Y will use the same register. + X = X0 band 1, + Y = Y0 band 3, + case Y of + 0 -> zero; + 1 -> one; + 2 -> two; + 3 -> three + end. + coverage(_Config) -> {'EXIT',{badarith,_}} = (catch id(1) bsl 0.5), {'EXIT',{badarith,_}} = (catch id(2.0) bsl 2), |