File 1161-Eliminate-unsafe-fusion-of-BEAM-instructions.patch of Package erlang

From 434f8b4f61953a5140367a8934251107403dacb3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Thu, 3 Oct 2024 09:51:50 +0200
Subject: [PATCH] Eliminate unsafe fusion of BEAM instructions

Closes #8875
---
 erts/emulator/beam/jit/arm/ops.tab |  4 ++--
 erts/emulator/beam/jit/x86/ops.tab |  2 +-
 erts/emulator/test/tuple_SUITE.erl | 38 ++++++++++++++++++++++++++++--
 3 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/erts/emulator/beam/jit/arm/ops.tab b/erts/emulator/beam/jit/arm/ops.tab
index e7fe144772..73266ec4a0 100644
--- a/erts/emulator/beam/jit/arm/ops.tab
+++ b/erts/emulator/beam/jit/arm/ops.tab
@@ -210,11 +210,11 @@ current_tuple/1
 current_tuple/2
 
 is_tuple Fail=f Src | test_arity Fail2 Src2 Arity |
-  equal(Fail, Fail2) | equal(Src, Src) =>
+  equal(Fail, Fail2) | equal(Src, Src2) =>
     i_is_tuple_of_arity Fail Src Arity | current_tuple Src
 
 is_tuple Fail1=f Src | test_arity Fail2 Src2 Arity |
-  equal(Src, Src) =>
+  equal(Src, Src2) =>
     i_is_tuple_of_arity_ff Fail1 Fail2 Src Arity | current_tuple Src
 
 test_arity Fail Src Arity => i_test_arity Fail Src Arity | current_tuple Src
diff --git a/erts/emulator/beam/jit/x86/ops.tab b/erts/emulator/beam/jit/x86/ops.tab
index d73435be65..f8a46e1453 100644
--- a/erts/emulator/beam/jit/x86/ops.tab
+++ b/erts/emulator/beam/jit/x86/ops.tab
@@ -218,7 +218,7 @@ is_tuple Fail=f Src | test_arity Fail2 Src2 Arity |
     i_is_tuple_of_arity Fail Src Arity | current_tuple Src
 
 is_tuple Fail1=f Src | test_arity Fail2 Src2 Arity |
-  equal(Src, Src) =>
+  equal(Src, Src2) =>
     i_is_tuple_of_arity_ff Fail1 Fail2 Src Arity | current_tuple Src
 
 test_arity Fail Src Arity => i_test_arity Fail Src Arity | current_tuple Src
diff --git a/erts/emulator/test/tuple_SUITE.erl b/erts/emulator/test/tuple_SUITE.erl
index 11967b78f3..ae4c59e7b6 100644
--- a/erts/emulator/test/tuple_SUITE.erl
+++ b/erts/emulator/test/tuple_SUITE.erl
@@ -26,7 +26,8 @@
 	 t_make_tuple_2/1, t_make_upper_boundry_tuple_2/1, t_make_tuple_3/1,
 	 t_append_element/1, t_append_element_upper_boundry/1,
          build_and_match/1, tuple_with_case/1, tuple_in_guard/1,
-         get_two_tuple_elements/1]).
+         get_two_tuple_elements/1,
+         bad_tuple_match/1]).
 -include_lib("common_test/include/ct.hrl").
 
 %% Tests tuples and the BIFs:
@@ -49,7 +50,8 @@ all() ->
      t_append_element, t_append_element_upper_boundry,
      t_insert_element, t_delete_element,
      tuple_with_case, tuple_in_guard,
-     get_two_tuple_elements].
+     get_two_tuple_elements,
+     bad_tuple_match].
 
 groups() -> 
     [].
@@ -630,6 +632,39 @@ get_two_tuple_elements(Config) ->
 
     ok.
 
+%% GH-8875
+bad_tuple_match(_Config) ->
+    ContentName = id(~"content-name"),
+    Content = id(#{ContentName => value}),
+
+    Find = case maps:find(ContentName, Content) of
+               {ok, _} -> {ok1, aa};
+               error -> ok
+           end,
+
+    Details = try id(good) of
+                  good ->
+                      {ok2, bb, cc}
+              catch
+                  _:_ ->
+                      {error, some_reason}
+              end,
+
+    %% Compiler optimizations will turn the following two lines into:
+    %%
+    %%    {test,is_tuple,Fail1,[{y,0}]}
+    %%    {test,test_arity,Fail2,[{x,0},3]}.
+    %%
+    %% The JIT would rewrite that to:
+    %%
+    %%    {i_is_tuple_of_arity_ff,Fail1,Fail2,{y,0},3}
+    %%
+    %% That is unsafe because the source tuples are distinct.
+    {ok1, _} = Find,
+    {ok2, _, _} = Details,
+
+    ok.
+
 %% Use this function to avoid compile-time evaluation of an expression.
 id(I) -> I.
 
-- 
2.43.0

openSUSE Build Service is sponsored by