File 0253-Fix-incorrect-type-interference-of-integer-ranges.patch of Package erlang

From c455dc2ca108e8ffbf5431068223fcff8aeb5361 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Mon, 29 Jan 2018 13:00:18 +0100
Subject: [PATCH] Fix incorrect type interference of integer ranges

---
 lib/compiler/src/beam_type.erl        |  8 ++++----
 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
@@ -887,10 +887,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
@@ -62,6 +62,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) ->
@@ -84,6 +93,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),
-- 
2.16.0

openSUSE Build Service is sponsored by