aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-05-21 14:48:11 +0200
committerBjörn Gustavsson <[email protected]>2019-05-21 15:32:25 +0200
commit7173fb8984d1822cc9c081f094841fb755f800fc (patch)
tree7c4258089de470fff4ed035ee54d5d79676ed97c /lib/compiler/src
parentd32991afaf3fc5f9f73e3e2448672bb9a1b80101 (diff)
downloadotp-7173fb8984d1822cc9c081f094841fb755f800fc.tar.gz
otp-7173fb8984d1822cc9c081f094841fb755f800fc.tar.bz2
otp-7173fb8984d1822cc9c081f094841fb755f800fc.zip
Eliminate compiler crash when compiling complex receive statements
Certain complex receive statements would result in an internal compiler failure. That would happen when the compiler would fail to find the common exit block following a receive. See the added test case for an example. https://bugs.erlang.org/browse/ERL-950
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/beam_ssa_pre_codegen.erl11
1 files changed, 7 insertions, 4 deletions
diff --git a/lib/compiler/src/beam_ssa_pre_codegen.erl b/lib/compiler/src/beam_ssa_pre_codegen.erl
index bf99e8fc26..9af72afca7 100644
--- a/lib/compiler/src/beam_ssa_pre_codegen.erl
+++ b/lib/compiler/src/beam_ssa_pre_codegen.erl
@@ -1415,12 +1415,15 @@ fix_receive([], _Defs, Blocks, Count) ->
find_loop_exit([L1,L2|_Ls], Blocks) ->
Path1 = beam_ssa:rpo([L1], Blocks),
Path2 = beam_ssa:rpo([L2], Blocks),
- find_loop_exit_1(reverse(Path1), reverse(Path2), none);
+ find_loop_exit_1(Path1, cerl_sets:from_list(Path2));
find_loop_exit(_, _) -> none.
-find_loop_exit_1([H|T1], [H|T2], _) ->
- find_loop_exit_1(T1, T2, H);
-find_loop_exit_1(_, _, Exit) -> Exit.
+find_loop_exit_1([H|T], OtherPath) ->
+ case cerl_sets:is_element(H, OtherPath) of
+ true -> H;
+ false -> find_loop_exit_1(T, OtherPath)
+ end;
+find_loop_exit_1([], _) -> none.
%% find_rm_blocks(StartLabel, Blocks) -> [Label].
%% Find all blocks that start with remove_message within the receive