summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrej Drejhammar <frej.drejhammar@gmail.com>2023-03-10 08:34:59 +0100
committerFrej Drejhammar <frej.drejhammar@gmail.com>2023-03-10 09:54:05 +0100
commit0bac830c937c7c39b6aae37a73bd135841dde969 (patch)
tree1ad21e5496b2425ebc7f37ad7f9f931dac25aaa0
parent8130d7ff72b9a7344bbf38ae11283eb01aab3ae5 (diff)
downloaderlang-0bac830c937c7c39b6aae37a73bd135841dde969.tar.gz
compiler: Be stricter when tracking values in private append
Tracking values to patch into writable binaries in the private append pass doesn't make any attempt to use type information to exclude execution paths not relevant when tracking an appendable binary. In order to avoid later failed attempts to rewrite non-bitstring literals into bs_init_writable-created values during the rewrite phase, we change the tracking phase to preemptively abort tracking as soon as we detect that the element we are tracking can't apply to the literal. Closes #6999
-rw-r--r--lib/compiler/src/beam_ssa_private_append.erl32
-rw-r--r--lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl13
2 files changed, 36 insertions, 9 deletions
diff --git a/lib/compiler/src/beam_ssa_private_append.erl b/lib/compiler/src/beam_ssa_private_append.erl
index aab7d73936..bb68dc12f9 100644
--- a/lib/compiler/src/beam_ssa_private_append.erl
+++ b/lib/compiler/src/beam_ssa_private_append.erl
@@ -167,16 +167,30 @@ 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],
+get_results([{Lbl,#b_blk{last=#b_ret{arg=#b_literal{val=Lit}}}}|Rest],
Acc, Element, Fun, DefSt0) ->
- DefSt = add_literal(Fun, {ret,Lbl,Element}, DefSt0),
+ %% As tracking doesn't make any attempt to use type information to
+ %% exclude execution paths not relevant when tracking an
+ %% appendable binary, it can happen that we encounter literals
+ %% which do not match the type of the element. We can safely stop
+ %% the tracking in that case.
+ Continue = case Element of
+ {tuple_elements,_} ->
+ is_tuple(Lit);
+ {tuple_element,_,_} ->
+ is_tuple(Lit);
+ Elements when is_list(Elements) ->
+ is_tuple(Lit);
+ self ->
+ is_bitstring(Lit);
+ {hd,_} ->
+ is_list(Lit) andalso (Lit =/= [])
+ end,
+ DefSt = if Continue ->
+ add_literal(Fun, {ret,Lbl,Element}, DefSt0);
+ true ->
+ DefSt0
+ end,
get_results(Rest, Acc, Element, Fun, DefSt);
get_results([_|Rest], Acc, Element, Fun, DefSt) ->
get_results(Rest, Acc, Element, Fun, DefSt);
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 508bc90c81..881cbeccee 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
@@ -58,6 +58,7 @@
transformable31b/1,
transformable32/0,
transformable32/1,
+ transformable33/0,
not_transformable1/2,
not_transformable2/1,
@@ -749,6 +750,18 @@ transformable32(#{}) ->
transformable32(_) ->
<<>>.
+%% Check that we don't crash (Github issue #6999) while attempting to
+%% patch the empty list, but also that Dest is created with private_append.
+transformable33() ->
+%ssa% () when post_ssa_opt ->
+%ssa% _ = bs_create_bin(private_append, ...).
+ [F01] = [transformable33_inner(<<"0">>) || _ <- [1]],
+ Dest = <<F01/binary>>,
+ Dest.
+
+transformable33_inner(V) ->
+ << <<C>> || <<C:4>> <= V >>.
+
% 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 ->