diff --git a/lib/compiler/src/beam_ssa_private_append.erl b/lib/compiler/src/beam_ssa_private_append.erl index 0ace5cca622a..19c38854f707 100644 --- a/lib/compiler/src/beam_ssa_private_append.erl +++ b/lib/compiler/src/beam_ssa_private_append.erl @@ -168,6 +168,13 @@ get_results(SSA, Element, Fun, DefSt) -> get_results([{_,#b_blk{last=#b_ret{arg=#b_var{}=V}}}|Rest], Acc, Element, Fun, DefSt) -> get_results(Rest, [{V,Element}|Acc], Element, Fun, DefSt); +get_results([{_,#b_blk{last=#b_ret{arg=#b_literal{val=Lit}}}}|Rest], + Acc, Element=self, Fun, DefSt) when not is_bitstring(Lit) -> + %% As value tracking is done without type information, we can + %% follow def chains which don't terminate in a bitstring. This is + %% harmless, but we should ignore them and not, later on, try to + %% patch them to a bs_writable_binary. + get_results(Rest, Acc, Element, Fun, DefSt); get_results([{Lbl,#b_blk{last=#b_ret{arg=#b_literal{}}}}|Rest], Acc, Element, Fun, DefSt0) -> DefSt = add_literal(Fun, {ret,Lbl,Element}, DefSt0), diff --git a/lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl b/lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl index d0ac4fb5c848..ddc091384dea 100644 --- a/lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl +++ b/lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl @@ -57,6 +57,8 @@ transformable30/1, transformable31a/1, transformable31b/1, + transformable32/0, + transformable32/1, not_transformable1/2, not_transformable2/1, @@ -748,6 +750,20 @@ transformable31([], Acc, a) when is_binary(Acc) -> transformable31([], Acc, b) when is_tuple(Acc) -> <<>>. +%% Check that we don't crash (Github issue #6847) while attempting to +%% patch the empty list, but also that the literal <<>> becomes a +%% bs_init_writable. +transformable32() -> + <<(transformable32(ok))/binary>>. + +transformable32(#{}) -> +%ssa% (_) when post_ssa_opt -> +%ssa% A = bs_init_writable(_), +%ssa% ret(A). + []; +transformable32(_) -> + <<>>. + % Should not be transformed as we can't know the alias status of Acc not_transformable1([H|T], Acc) -> %ssa% (_, Arg1) when post_ssa_opt ->