diff options
author | Björn Gustavsson <[email protected]> | 2019-05-21 14:48:11 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2019-05-21 15:32:25 +0200 |
commit | 7173fb8984d1822cc9c081f094841fb755f800fc (patch) | |
tree | 7c4258089de470fff4ed035ee54d5d79676ed97c /lib/compiler/src | |
parent | d32991afaf3fc5f9f73e3e2448672bb9a1b80101 (diff) | |
download | otp-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.erl | 11 |
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 |