diff options
author | Erlang/OTP <[email protected]> | 2019-05-29 13:24:41 +0200 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2019-05-29 13:24:41 +0200 |
commit | 1f61a273a53ac8fe48be1de0c86b33c82a84ebbd (patch) | |
tree | be78aff78593351f3af0037cc184a53a1c56b8a6 | |
parent | 787a7684b02a01818eb99abc0f6a168250e192a9 (diff) | |
parent | 7173fb8984d1822cc9c081f094841fb755f800fc (diff) | |
download | otp-1f61a273a53ac8fe48be1de0c86b33c82a84ebbd.tar.gz otp-1f61a273a53ac8fe48be1de0c86b33c82a84ebbd.tar.bz2 otp-1f61a273a53ac8fe48be1de0c86b33c82a84ebbd.zip |
Merge branch 'bjorn/compiler/fix-receive-patch/ERL-950/OTP-15832' into maint-22
* bjorn/compiler/fix-receive-patch/ERL-950/OTP-15832:
Eliminate compiler crash when compiling complex receive statements
-rw-r--r-- | lib/compiler/src/beam_ssa_pre_codegen.erl | 11 | ||||
-rw-r--r-- | lib/compiler/test/receive_SUITE.erl | 26 |
2 files changed, 31 insertions, 6 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 diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl index 0038eb1a4b..752491f0f8 100644 --- a/lib/compiler/test/receive_SUITE.erl +++ b/lib/compiler/test/receive_SUITE.erl @@ -26,7 +26,7 @@ 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,double_recv/1,receive_var_zero/1, - match_built_terms/1]). + match_built_terms/1,elusive_common_exit/1]). -include_lib("common_test/include/ct.hrl"). @@ -47,7 +47,7 @@ groups() -> [{p,test_lib:parallel(), [recv,coverage,otp_7980,ref_opt,export,wait, recv_in_try,double_recv,receive_var_zero, - match_built_terms]}]. + match_built_terms,elusive_common_exit]}]. init_per_suite(Config) -> @@ -427,4 +427,26 @@ match_built_terms(Config) when is_list(Config) -> ?MATCH_BUILT_TERM(Ref, <<A, B>>), ?MATCH_BUILT_TERM(Ref, #{ 1 => A, 2 => B}). +elusive_common_exit(_Config) -> + self() ! {1, a}, + self() ! {2, b}, + {[z], [{2,b},{1,a}]} = elusive_loop([x,y,z], 2, []), + ok. + +elusive_loop(List, 0, Results) -> + {List, Results}; +elusive_loop(List, ToReceive, Results) -> + {Result, RemList} = + receive + {_Pos, _R} = Res when List =/= [] -> + [_H|T] = List, + {Res, T}; + {_Pos, _R} = Res when List =:= [] -> + {Res, []} + end, + %% beam_ssa_pre_codegen:fix_receives() would fail to find + %% the common exit block for this receive. That would mean + %% that it would not insert all necessary copy instructions. + elusive_loop(RemList, ToReceive-1, [Result | Results]). + id(I) -> I. |