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