From 66ad2bda5332d14ed39439f21e144a022f49e209 Mon Sep 17 00:00:00 2001 From: Frej Drejhammar Date: Wed, 2 Aug 2023 14:23:50 +0200 Subject: [PATCH] compiler: Fix crash in beam_ssa_private_append The beam_ssa_private_append pass can 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. This patch changes the beam_ssa_private_append pass to simply stop tracking a value when it is known that the type is not compatible. --- lib/compiler/src/beam_ssa_private_append.erl | 4 +-- .../private_append.erl | 26 ++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) 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).