aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-08-14 16:06:52 +0200
committerBjörn Gustavsson <[email protected]>2018-08-14 16:24:30 +0200
commitec8ae4b539bcb4b4eedf8dd3eb1e7bcdfe558580 (patch)
tree9e5b28477fb01ddbad9e71297e45e94a7af2512d /lib
parent4fc61aa178faa80290356a63d8e38d93697b9669 (diff)
downloadotp-ec8ae4b539bcb4b4eedf8dd3eb1e7bcdfe558580.tar.gz
otp-ec8ae4b539bcb4b4eedf8dd3eb1e7bcdfe558580.tar.bz2
otp-ec8ae4b539bcb4b4eedf8dd3eb1e7bcdfe558580.zip
Fix compiler crash when compiling double receives
The compiler would crash when compiling a function with two receive statements. https://bugs.erlang.org/browse/ERL-703
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/beam_utils.erl2
-rw-r--r--lib/compiler/test/receive_SUITE.erl32
2 files changed, 31 insertions, 3 deletions
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index 3bb671f034..5580d2f123 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -1164,7 +1164,7 @@ defs([{loop_rec,{f,L},{x,0}}=I|Is], _Regs, D0) ->
D = update_regs(L, RegsAtLabel, D0),
[I|defs(Is, init_def_regs(1), D)];
defs([{loop_rec_end,_}=I|Is], _Regs, D) ->
- [I|defs(Is, 0, D)];
+ [I|defs_unreachable(Is, D)];
defs([{make_fun2,_,_,_,_}=I|Is], _Regs, D) ->
[I|defs(Is, 1, D)];
defs([{move,_,Dst}=I|Is], Regs0, D) ->
diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl
index 37e737084a..4219768d6f 100644
--- a/lib/compiler/test/receive_SUITE.erl
+++ b/lib/compiler/test/receive_SUITE.erl
@@ -25,7 +25,7 @@
init_per_group/2,end_per_group/2,
init_per_testcase/2,end_per_testcase/2,
export/1,recv/1,coverage/1,otp_7980/1,ref_opt/1,
- wait/1,recv_in_try/1]).
+ wait/1,recv_in_try/1,double_recv/1]).
-include_lib("common_test/include/ct.hrl").
@@ -45,7 +45,7 @@ all() ->
groups() ->
[{p,test_lib:parallel(),
[recv,coverage,otp_7980,ref_opt,export,wait,
- recv_in_try]}].
+ recv_in_try,double_recv]}].
init_per_suite(Config) ->
@@ -349,5 +349,33 @@ recv_in_try(Timeout, Format) ->
{nok,Reason}
end.
+%% ERL-703. The compiler would crash because beam_utils:anno_defs/1
+%% failed to take into account that code after loop_rec_end is
+%% unreachable.
+
+double_recv(_Config) ->
+ self() ! {more,{a,term}},
+ ok = do_double_recv({more,{a,term}}, any),
+ self() ! message,
+ ok = do_double_recv(whatever, message),
+
+ error = do_double_recv({more,42}, whatever),
+ error = do_double_recv(whatever, whatever),
+ ok.
+
+do_double_recv({more, Rest}, _Msg) ->
+ receive
+ {more, Rest} ->
+ ok
+ after 0 ->
+ error
+ end;
+do_double_recv(_, Msg) ->
+ receive
+ Msg ->
+ ok
+ after 0 ->
+ error
+ end.
id(I) -> I.