File 2811-v3_core-Eliminate-crash-when-no-receive-clauses-coul.patch of Package erlang
From 051ecbc1b3b78d9ea1600382a827237f73ef6c6c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Fri, 14 Feb 2020 06:58:00 +0100
Subject: [PATCH 6/6] v3_core: Eliminate crash when no receive clauses could
match
The following code would crash the compiler:
foobar() ->
receive
a = b ->
V = a
end,
V.
---
lib/compiler/src/v3_core.erl | 14 ++++++++++++++
lib/compiler/test/receive_SUITE.erl | 15 +++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index a20595c131..9e2ca45074 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -2191,6 +2191,20 @@ uexprs([#imatch{anno=A,pat=P0,arg=Arg,fc=Fc}|Les], Ks, St0) ->
uexprs([#icase{anno=A,args=[Arg],
clauses=[Mc],fc=Fc}], Ks, St0)
end;
+uexprs([#ireceive1{clauses=[]}=Le0|_], Ks, St0) ->
+ %% All clauses have been optimized away because they had impossible patterns.
+ %% For example:
+ %%
+ %% receive
+ %% a = b ->
+ %% V = whatever
+ %% end,
+ %% V
+ %%
+ %% Discard the unreachable code following the receive to ensure
+ %% that there are no references to unbound variables.
+ {Le1,St1} = uexpr(Le0, Ks, St0),
+ {[Le1],St1};
uexprs([Le0|Les0], Ks, St0) ->
{Le1,St1} = uexpr(Le0, Ks, St0),
{Les1,St2} = uexprs(Les0, union((get_anno(Le1))#a.ns, Ks), St1),
diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl
index dd70925ff7..b1f1099095 100644
--- a/lib/compiler/test/receive_SUITE.erl
+++ b/lib/compiler/test/receive_SUITE.erl
@@ -145,6 +145,11 @@ coverage(Config) when is_list(Config) ->
ok = receive_sink_tuple({any,pattern}),
{b,a} = receive_sink_tuple({a,b}),
+ %% Basically a smoke test of no_clauses_left/0.
+ NoClausesLeft = spawn(fun no_clauses_left/0),
+ receive after 1 -> ok end,
+ exit(NoClausesLeft, kill),
+
ok.
monitor_plus_badmap(Pid) ->
@@ -193,6 +198,16 @@ tuple_to_values(Timeout, X) ->
end,
A+B.
+no_clauses_left() ->
+ receive
+ %% This clause would be removed because it cannot match...
+ a = b ->
+ V = whatever
+ end,
+ %% ... leaving a reference to an unbound variable. Crash.
+ V.
+
+
%% Cover a help function for beam_ssa_opt:ssa_opt_sink/1.
receive_sink_tuple({Line,Pattern}) ->
receive
--
2.16.4