File 8121-Eliminate-an-unsafe-optimization-of-list-matching.patch of Package erlang

From f441ac970f7d6e930822c61ebdab3e40c0d38485 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Mon, 26 Feb 2024 07:33:13 +0100
Subject: [PATCH] Eliminate an unsafe optimization of list matching

In rare circumstances, the compiler could do an unsafe rewrite of
list matching operations. For example:

    [PrevRow | _] = Rows,
    [_ | PrevRowT] = PrevRow,
    . . .

Provided that the type analysis pass had figured out that `Rows` is
always a list of at least two elements, the compiler would essentially
rewrite the code to:

    [PrevRow | PrevRowT] = Rows,
    . . .

Fixes #8187
---
 lib/compiler/src/beam_z.erl     |  4 ++--
 lib/compiler/test/bif_SUITE.erl | 17 +++++++++++++++++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/lib/compiler/src/beam_z.erl b/lib/compiler/src/beam_z.erl
index 9f467676e5..71160d47fa 100644
--- a/lib/compiler/src/beam_z.erl
+++ b/lib/compiler/src/beam_z.erl
@@ -85,9 +85,9 @@ undo_renames([{bif,raise,_,_,_}=I|Is0]) ->
 		      (_) -> true
 		   end, Is0),
     [I|undo_renames(Is)];
-undo_renames([{get_hd,Src,Hd},{get_tl,Src,Tl}|Is]) ->
+undo_renames([{get_hd,Src,Hd},{get_tl,Src,Tl}|Is]) when Src =/= Hd ->
     get_list(Src, Hd, Tl, Is);
-undo_renames([{get_tl,Src,Tl},{get_hd,Src,Hd}|Is]) ->
+undo_renames([{get_tl,Src,Tl},{get_hd,Src,Hd}|Is]) when Src =/= Tl ->
     get_list(Src, Hd, Tl, Is);
 undo_renames([{bs_put,_,{bs_put_binary,1,_},
                [{atom,all},{literal,<<>>}]}|Is]) ->
diff --git a/lib/compiler/test/bif_SUITE.erl b/lib/compiler/test/bif_SUITE.erl
index a23d728715..4137f43f91 100644
--- a/lib/compiler/test/bif_SUITE.erl
+++ b/lib/compiler/test/bif_SUITE.erl
@@ -23,6 +23,7 @@
 
 -export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
 	 init_per_group/2,end_per_group/2,
+         unsafe_get_list/1,
 	 beam_validator/1,trunc_and_friends/1,cover_safe_and_pure_bifs/1,
          min_max/1]).
 
@@ -37,6 +38,7 @@ all() ->
 groups() ->
     [{p,test_lib:parallel(),
       [beam_validator,
+       unsafe_get_list,
        trunc_and_friends,
        cover_safe_and_pure_bifs,
        min_max
@@ -57,6 +59,21 @@ init_per_group(_GroupName, Config) ->
 end_per_group(_GroupName, Config) ->
     Config.
 
+unsafe_get_list(_Config) ->
+    [[1], [1], [1]] = create_rows(id(3)),
+    ok.
+
+create_rows(Num) -> create_rows(Num, [[1]]).
+
+create_rows(1, Rows) ->
+    Rows;
+create_rows(Num, [PrevRow | _] = Rows) ->
+    [_PrevRowH | PrevRowT] = PrevRow,
+    [] = first(PrevRowT, PrevRow),
+    create_rows(Num - 1, [[1] | Rows]).
+
+first(Fst, _Snd) -> Fst.
+
 %% Cover code in beam_validator.
 
 beam_validator(Config) ->
-- 
2.35.3

openSUSE Build Service is sponsored by