diff options
author | Björn Gustavsson <[email protected]> | 2019-08-13 06:38:24 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2019-08-14 07:10:17 +0200 |
commit | c5e36feada9d0362108890f42c40dd2398b1b531 (patch) | |
tree | 802db75152357454c28ea42680ccfa8d45d0b355 /lib/compiler/test | |
parent | d203e847548586f6ef80ac0e73a5f6f173efe1c6 (diff) | |
download | otp-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')
-rw-r--r-- | lib/compiler/test/receive_SUITE.erl | 35 |
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. |