File 0450-Fix-a-bug-where-the-make_fun-instruction-would-not-f.patch of Package erlang

From aeb537ff839342516861b46697556690bc193f22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Tue, 3 Mar 2020 15:54:42 +0100
Subject: [PATCH 30/30] Fix a bug where the make_fun instruction would not
 force a stack frame

If optimization passes were disabled, there would not be a stack
frame for this function (causing beam_validator to reject the program):

    ff(_, V) ->
        fun() -> [] end,
        V.
---
 lib/compiler/src/beam_ssa_pre_codegen.erl | 25 +++++++++++++++++--------
 lib/compiler/test/beam_ssa_SUITE.erl      |  6 ++++++
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/lib/compiler/src/beam_ssa_pre_codegen.erl b/lib/compiler/src/beam_ssa_pre_codegen.erl
index bc8db04593..afaef84aff 100644
--- a/lib/compiler/src/beam_ssa_pre_codegen.erl
+++ b/lib/compiler/src/beam_ssa_pre_codegen.erl
@@ -1327,14 +1327,23 @@ need_frame(#b_blk{is=Is,last=#b_ret{arg=Ret}}) ->
 need_frame(#b_blk{is=Is}) ->
     need_frame_1(Is, body).
 
-need_frame_1([#b_set{op=make_fun,dst=Fun}|Is], {return,_}=Context) ->
-    %% Since make_fun clobbers X registers, a stack frame is needed if
-    %% any of the following instructions use any other variable than
-    %% the one holding the reference to the created fun.
-    need_frame_1(Is, Context) orelse
-        case beam_ssa:used(#b_blk{is=Is,last=#b_ret{arg=Fun}}) of
-            [Fun] -> false;
-            [_|_] -> true
+need_frame_1([#b_set{op=make_fun,dst=Fun}|Is], {return,Ret}=Context) ->
+    case need_frame_1(Is, Context) of
+        true ->
+            true;
+        false ->
+            %% Since make_fun clobbers X registers, a stack frame is
+            %% needed if any of the following instructions use any
+            %% other variable than the one holding the reference to
+            %% the created fun.
+            Defs = ordsets:from_list([Dst || #b_set{dst=Dst} <- Is]),
+            Blk = #b_blk{is=Is,last=#b_ret{arg=Ret}},
+            Used = ordsets:subtract(beam_ssa:used(Blk), Defs),
+            case Used of
+                [] -> false;
+                [Fun] -> false;
+                [_|_] -> true
+            end
         end;
 need_frame_1([#b_set{op=new_try_tag}|_], _) ->
     true;
-- 
2.16.4

openSUSE Build Service is sponsored by