Skip to content

Commit 73d93d8

Browse files
authored
Merge pull request #6862 from frej/frej/private-append-crash-gh6847
compiler: Avoid crash in private-append optimization
2 parents 2665bc5 + 1752215 commit 73d93d8

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

lib/compiler/src/beam_ssa_private_append.erl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,13 @@ get_results(SSA, Element, Fun, DefSt) ->
165165
get_results([{_,#b_blk{last=#b_ret{arg=#b_var{}=V}}}|Rest],
166166
Acc, Element, Fun, DefSt) ->
167167
get_results(Rest, [{V,Element}|Acc], Element, Fun, DefSt);
168+
get_results([{_,#b_blk{last=#b_ret{arg=#b_literal{val=Lit}}}}|Rest],
169+
Acc, Element=self, Fun, DefSt) when not is_bitstring(Lit) ->
170+
%% As value tracking is done without type information, we can
171+
%% follow def chains which don't terminate in a bitstring. This is
172+
%% harmless, but we should ignore them and not, later on, try to
173+
%% patch them to a bs_writable_binary.
174+
get_results(Rest, Acc, Element, Fun, DefSt);
168175
get_results([{Lbl,#b_blk{last=#b_ret{arg=#b_literal{}}}}|Rest],
169176
Acc, Element, Fun, DefSt0) ->
170177
DefSt = add_literal(Fun, {ret,Lbl,Element}, DefSt0),

lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
transformable30/1,
5757
transformable31a/1,
5858
transformable31b/1,
59+
transformable32/0,
60+
transformable32/1,
5961

6062
not_transformable1/2,
6163
not_transformable2/1,
@@ -732,6 +734,20 @@ transformable31([], Acc, a) when is_binary(Acc) ->
732734
transformable31([], Acc, b) when is_tuple(Acc) ->
733735
<<>>.
734736

737+
%% Check that we don't crash (Github issue #6847) while attempting to
738+
%% patch the empty list, but also that the literal <<>> becomes a
739+
%% bs_init_writable.
740+
transformable32() ->
741+
<<(transformable32(ok))/binary>>.
742+
743+
transformable32(#{}) ->
744+
%ssa% (_) when post_ssa_opt ->
745+
%ssa% A = bs_init_writable(_),
746+
%ssa% ret(A).
747+
[];
748+
transformable32(_) ->
749+
<<>>.
750+
735751
% Should not be transformed as we can't know the alias status of Acc
736752
not_transformable1([H|T], Acc) ->
737753
%ssa% (_, Arg1) when post_ssa_opt ->

0 commit comments

Comments
 (0)