diff options
author | John Högberg <john@erlang.org> | 2023-04-21 17:58:18 +0200 |
---|---|---|
committer | John Högberg <john@erlang.org> | 2023-04-21 18:51:56 +0200 |
commit | d50da87df5223baa8f18ed91dc5727de47fce26a (patch) | |
tree | 1db3159c115ebebe13bc813dc6f41acd86467ee7 /lib/compiler | |
parent | 15d0c80ec768319265e1d30898f8cde6c298483e (diff) | |
download | erlang-d50da87df5223baa8f18ed91dc5727de47fce26a.tar.gz |
beam_ssa_private_append: Fix crash on oddly structured code
The private append pass didn't expect to append anything
to literals other than `<<>>`. Rare interactions with the type
or bool passes could sneak in things like atoms in unexpected
places, crashing the pass.
Diffstat (limited to 'lib/compiler')
-rw-r--r-- | lib/compiler/src/beam_ssa_private_append.erl | 2 | ||||
-rw-r--r-- | lib/compiler/test/bs_construct_SUITE.erl | 11 |
2 files changed, 11 insertions, 2 deletions
diff --git a/lib/compiler/src/beam_ssa_private_append.erl b/lib/compiler/src/beam_ssa_private_append.erl index 3f2e3715ec..bf51e8b81a 100644 --- a/lib/compiler/src/beam_ssa_private_append.erl +++ b/lib/compiler/src/beam_ssa_private_append.erl @@ -565,6 +565,8 @@ patch_literal_term(<<>>, self, Cnt0) -> {V,Cnt} = new_var(Cnt0), I = #b_set{op=bs_init_writable,dst=V,args=[#b_literal{val=256}]}, {V, [I], Cnt}; +patch_literal_term(Lit, self, Cnt) -> + {#b_literal{val=Lit}, [], Cnt}; patch_literal_term([H0|T0], {hd,Element}, Cnt0) -> {H,Extra,Cnt1} = patch_literal_term(H0, Element, Cnt0), {T,[],Cnt1} = patch_literal_term(T0, [], Cnt1), diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl index 73920fbad1..bc6ed43dad 100644 --- a/lib/compiler/test/bs_construct_SUITE.erl +++ b/lib/compiler/test/bs_construct_SUITE.erl @@ -755,18 +755,25 @@ bad_binary_size2() -> bad_binary_size3(Bin) -> <<Bin:all/binary>>. -%% GH-7121: Alias analysis would not mark fun arguments as aliased, fooling -%% the beam_ssa_private_append pass. private_append(_Config) -> <<"alpha=\"alpha\",beta=\"beta\"">> = private_append_1(#{ <<"alpha">> => <<"alpha">>, <<"beta">> => <<"beta">> }), + <<>> = private_append_2(false), + {'EXIT', _} = catch private_append_2(true), + ok. +%% GH-7121: Alias analysis would not mark fun arguments as aliased, fooling +%% the beam_ssa_private_append pass. private_append_1(M) when is_map(M) -> maps:fold(fun (K, V, Acc = <<>>) -> <<Acc/binary, K/binary, "=\"", V/binary, "\"">>; (K, V, Acc) -> <<Acc/binary, ",", K/binary, "=\"", V/binary, "\"">> end, <<>>, M). + +%% GH-7142: The private append pass crashed on oddly structured code. +private_append_2(Boolean) -> + <<<<(id(Boolean) orelse <<>>)/binary>>/binary>>. |