diff options
author | Björn Gustavsson <[email protected]> | 2018-01-29 13:00:18 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2018-01-29 15:29:06 +0100 |
commit | c455dc2ca108e8ffbf5431068223fcff8aeb5361 (patch) | |
tree | c0d7b7a54b9d5091e6b897b87e5c76e1ce2a14f3 | |
parent | db9e04d0f4337a2b32376a41275ecedfe0258c1f (diff) | |
download | otp-c455dc2ca108e8ffbf5431068223fcff8aeb5361.tar.gz otp-c455dc2ca108e8ffbf5431068223fcff8aeb5361.tar.bz2 otp-c455dc2ca108e8ffbf5431068223fcff8aeb5361.zip |
Fix incorrect type interference of integer ranges
-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 c8abfa524f..fc2c7a991b 100644 --- a/lib/compiler/src/beam_type.erl +++ b/lib/compiler/src/beam_type.erl @@ -914,10 +914,10 @@ merge_type_info({tuple,Sz1,[]}, {tuple,_Sz2,First}=Tuple2) -> merge_type_info({tuple,Sz1,First}, Tuple2); merge_type_info({tuple,_Sz1,First}=Tuple1, {tuple,Sz2,_}) -> merge_type_info(Tuple1, {tuple,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(NewType, _) -> diff --git a/lib/compiler/test/beam_type_SUITE.erl b/lib/compiler/test/beam_type_SUITE.erl index fe856b12b6..d44fa60997 100644 --- a/lib/compiler/test/beam_type_SUITE.erl +++ b/lib/compiler/test/beam_type_SUITE.erl @@ -66,6 +66,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) -> @@ -88,6 +97,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), |