File 4701-beam_validator-Improve-arithmetic-range-inference.patch of Package erlang

From 3b3e4625195443cfe9186b82cd556fd6b4c49ebf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20H=C3=B6gberg?= <john@erlang.org>
Date: Wed, 26 Apr 2023 07:31:27 +0200
Subject: [PATCH] beam_validator: Improve arithmetic range inference

Fixes #7171
---
 lib/compiler/src/beam_validator.erl        | 12 +++++++++++-
 lib/compiler/test/beam_validator_SUITE.erl | 21 +++++++++++++++++++--
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index f19ea897fe..c11b4b8a2f 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -3429,7 +3429,17 @@ bif_types(Op, Ss, Vst) ->
                     Other
             end;
         {_,_} ->
-            beam_call_types:types(erlang, Op, Args)
+            Res0 = beam_call_types:types(erlang, Op, Args),
+            {Ret0, ArgTypes, SubSafe} = Res0,
+
+            %% Match the non-converging range analysis done in
+            %% `beam_ssa_type:opt_ranges/1`. This is safe since the validator
+            %% doesn't have to worry about convergence.
+            case beam_call_types:arith_type({bif, Op}, Args) of
+                any -> Res0;
+                Ret0 -> Res0;
+                Ret -> {meet(Ret, Ret0), ArgTypes, SubSafe}
+            end
     end.
 
 join_tuple_elements(Tuple) ->
diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl
index 6b63f561c1..2092d7401a 100644
--- a/lib/compiler/test/beam_validator_SUITE.erl
+++ b/lib/compiler/test/beam_validator_SUITE.erl
@@ -43,7 +43,7 @@
          bs_saved_position_units/1,parent_container/1,
          container_performance/1,
          not_equal_inference/1,singleton_inference/1,
-         inert_update_type/1,
+         inert_update_type/1,range_inference/1,
          too_many_arguments/1]).
 
 -include_lib("common_test/include/ct.hrl").
@@ -80,7 +80,7 @@ groups() ->
        bs_saved_position_units,parent_container,
        container_performance,
        not_equal_inference,singleton_inference,
-       inert_update_type,
+       inert_update_type,range_inference,
        too_many_arguments]}].
 
 init_per_suite(Config) ->
@@ -1129,6 +1129,23 @@ mike([Head | _Rest]) -> joe(Head).
 joe({Name, 42}) -> Name;
 joe({sys_period, {A, _B}}) -> {41, 42, A}.
 
+range_inference(_Config) ->
+    ok = range_inference_1(id(<<$a>>)),
+    ok = range_inference_1(id(<<0>>)),
+    ok = range_inference_1(id(<<1114111/utf8>>)),
+
+    ok.
+
+range_inference_1(<<X/utf8>>) ->
+    case 9223372036854775807 - abs(X) of
+        Y when X < Y ->
+            ok;
+        9223372036854775807 ->
+            ok;
+        -2147483648 ->
+            ok
+    end.
+
 %% GH-9113: We didn't reject funs, comprehensions, and the likes which exceeded
 %% the argument limit.
 too_many_arguments(_Config) ->
-- 
2.35.3

openSUSE Build Service is sponsored by