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

openSUSE Build Service is sponsored by