diff --git a/lib/compiler/src/beam_ssa_private_append.erl b/lib/compiler/src/beam_ssa_private_append.erl index 9c5a2ab1abf5..e1911f173b11 100644 --- a/lib/compiler/src/beam_ssa_private_append.erl +++ b/lib/compiler/src/beam_ssa_private_append.erl @@ -262,10 +262,10 @@ track_value_in_fun([{#b_var{}=V,Element}|Rest], Fun, Work0, Defs, Element, DefSt0), track_value_in_fun(ToExplore ++ Rest, Fun, Work0, Defs, ValuesInFun, DefSt); - {put_tuple,_,_} -> + {put_tuple,_,_} when Element =/= self -> track_put_tuple(Args, Element, Rest, Fun, V, Work0, Defs, ValuesInFun, DefSt0); - {put_list,_,_} -> + {put_list,_,_} when Element =/= self -> track_put_list(Args, Element, Rest, Fun, V, Work0, Defs, ValuesInFun, 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 bc9ee54c6a30..c522607b2d77 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 @@ -80,7 +80,10 @@ id/1, - bs_create_bin_on_literal/0]). + bs_create_bin_on_literal/0, + + crash_in_value_tracking/3, + crash_in_value_tracking_inner/3]). %% Trivial smoke test transformable0(L) -> @@ -1001,3 +1004,24 @@ bs_create_bin_on_literal() -> end)/bytes >>/binary >>. + +%% Check that the beam_ssa_private_append pass doesn't crash, if it, +%% during initial value tracking, ends up in operations which do not +%% create bit strings. This can happen as the initial value tracking +%% in beam_ssa_private_append doesn't consider types. As the decision +%% to apply the private append transform is using type information, +%% tracking values into not type-compatible execution paths is +%% harmless. +crash_in_value_tracking_inner(_, 1.0, _) -> +%ssa% (_, _, _) when post_ssa_opt -> +%ssa% _ = bs_init_writable(_). + (<<>>); +crash_in_value_tracking_inner(_V1, _, _) when _V1 -> + _V1. + +crash_in_value_tracking(_, _V0, _) -> +%ssa% (_, _, _) when post_ssa_opt -> +%ssa% _ = bs_create_bin(private_append, ...). + ((<<((crash_in_value_tracking_inner( + {#{#{ ok => ok || _ := _ <- ok} => ok}, + _V0, false, _V0, "Bo"}, _V0, ok)))/bytes>>) =/= ok).