aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/test/receive_SUITE.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-08-13 06:38:24 +0200
committerBjörn Gustavsson <[email protected]>2019-08-14 07:10:17 +0200
commitc5e36feada9d0362108890f42c40dd2398b1b531 (patch)
tree802db75152357454c28ea42680ccfa8d45d0b355 /lib/compiler/test/receive_SUITE.erl
parentd203e847548586f6ef80ac0e73a5f6f173efe1c6 (diff)
downloadotp-c5e36feada9d0362108890f42c40dd2398b1b531.tar.gz
otp-c5e36feada9d0362108890f42c40dd2398b1b531.tar.bz2
otp-c5e36feada9d0362108890f42c40dd2398b1b531.zip
Fix compiler crash when compiling some receive statements
The compiler would crash when compiling the following code: do(Acc) -> receive {Pid, abc} -> ok; {Pid, []} -> ok; {Pid, _Res} -> exit(_Res) end, do([Pid | Acc]). The last clause that always raises an exception would confuse the compiler so that it would think that the `receive` statement was at the end of the function and it would generate incorrect code for the `do/1` call following the `receive`. https://bugs.erlang.org/browse/ERL-1022
Diffstat (limited to 'lib/compiler/test/receive_SUITE.erl')
-rw-r--r--lib/compiler/test/receive_SUITE.erl35
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl
index 752491f0f8..8cd864c59e 100644
--- a/lib/compiler/test/receive_SUITE.erl
+++ b/lib/compiler/test/receive_SUITE.erl
@@ -431,6 +431,20 @@ elusive_common_exit(_Config) ->
self() ! {1, a},
self() ! {2, b},
{[z], [{2,b},{1,a}]} = elusive_loop([x,y,z], 2, []),
+
+ CodeServer = whereis(code_server),
+ Self = self(),
+ Self ! {Self, abc},
+ Self ! {CodeServer, []},
+ Self ! {Self, other},
+ try elusive2([]) of
+ Unexpected ->
+ ct:fail("Expected an exception; got ~p\n", [Unexpected])
+ catch
+ throw:[other, CodeServer, Self] ->
+ ok
+ end,
+
ok.
elusive_loop(List, 0, Results) ->
@@ -449,4 +463,25 @@ elusive_loop(List, ToReceive, Results) ->
%% that it would not insert all necessary copy instructions.
elusive_loop(RemList, ToReceive-1, [Result | Results]).
+
+elusive2(Acc) ->
+ receive
+ {Pid, abc} ->
+ ok;
+ {Pid, []} ->
+ ok;
+ {Pid, Res} ->
+ %% beam_ssa_pre_codegen:find_loop_exit/2 attempts to find
+ %% the first block of the common code after the receive
+ %% statement. It used to only look at the two last clauses
+ %% of the receive. In this function, the last two clauses
+ %% don't have any common block, so it would be assumed
+ %% that there was no common block for any of the
+ %% clauses. That would mean that copy instructions would
+ %% not be inserted as needed.
+ throw([Res | Acc])
+ end,
+ %% Common code.
+ elusive2([Pid | Acc]).
+
id(I) -> I.