summaryrefslogtreecommitdiff
path: root/lib/compiler/src/beam_a.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2019-10-25 13:26:30 +0200
committerBjörn Gustavsson <bjorn@erlang.org>2019-10-29 16:35:53 +0100
commit784b339a7f8e144e9299314c9ab88391b58460f0 (patch)
tree6c91ed2b4ce7ea6fc28328e63bbbbd7cd986771a /lib/compiler/src/beam_a.erl
parent6611181ae71422a1c66798718b37474641a090a9 (diff)
downloaderlang-784b339a7f8e144e9299314c9ab88391b58460f0.tar.gz
Fix unsafe optimization of receives
Fix a problem where a receive marker would be set even if it was not guaranteed that execution would reach a receive statement. See the new test case `receive_SUITE:return_before_receive/1` for an example where this would cause problems. https://bugs.erlang.org/browse/ERL-1076
Diffstat (limited to 'lib/compiler/src/beam_a.erl')
-rw-r--r--lib/compiler/src/beam_a.erl7
1 files changed, 7 insertions, 0 deletions
diff --git a/lib/compiler/src/beam_a.erl b/lib/compiler/src/beam_a.erl
index 0bccad1ecd..eadd858885 100644
--- a/lib/compiler/src/beam_a.erl
+++ b/lib/compiler/src/beam_a.erl
@@ -59,6 +59,13 @@ rename_instrs([{test,is_eq_exact,_,[Dst,Src]}=Test,
rename_instrs([{test,is_eq_exact,_,[Same,Same]}|Is]) ->
%% Same literal or same register. Will always succeed.
rename_instrs(Is);
+rename_instrs([{recv_set,_},
+ {label,Lbl},
+ {loop_rec,{f,Fail},{x,0}},
+ {loop_rec_end,_},{label,Fail}|Is]) ->
+ %% This instruction sequence does nothing. All we need to
+ %% keep is the first label.
+ [{label,Lbl}|rename_instrs(Is)];
rename_instrs([{loop_rec,{f,Fail},{x,0}},{loop_rec_end,_},{label,Fail}|Is]) ->
%% This instruction sequence does nothing.
rename_instrs(Is);