aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-01-31 10:17:53 +0100
committerBjörn Gustavsson <[email protected]>2018-01-31 10:17:53 +0100
commit2208953ca144858ddc343721a9cc40e43cc7fe0c (patch)
tree417bda1a7c739bf8a6dfa1df1cf486ae75d99dae /lib/compiler
parent1fe1c9a57d365c8203cb1380e4bdfe8f7f6ab8ce (diff)
parent2e5063371ca21eeabd9c20462c16fac0ee147028 (diff)
downloadotp-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.erl8
-rw-r--r--lib/compiler/test/beam_type_SUITE.erl33
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),