diff options
author | Frej Drejhammar <frej.drejhammar@gmail.com> | 2023-05-04 14:57:56 +0200 |
---|---|---|
committer | Frej Drejhammar <frej.drejhammar@gmail.com> | 2023-05-04 15:13:05 +0200 |
commit | 5277d99c337d85766dd8c087413ae7598390e743 (patch) | |
tree | 6bf85045575e9063018fe4d6432f63d3e79cd151 /lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl | |
parent | c9919949e055dea8f86d50ea7fef70eefd835e00 (diff) | |
download | erlang-5277d99c337d85766dd8c087413ae7598390e743.tar.gz |
compiler: Avoid invalid code for bs_create_bin with initial literal
This change stops the compiler from generating invalid code when
bs_create_bin is given a literal <<>> as its first fragment. As the
type analyzer considers a literal <<>> an appendable bitstring, code
sequences such as:
_6 = bs_create_bin `append`, `[8,{segment,1}]`, `<<>>`, `all`
...
_14 = bs_create_bin `append`, `[8,{segment,1}]`, _6, `all`
would be rewritten to:
_6 = bs_create_bin `private_append`, `[8,{segment,1}]`, `<<>>`, `all`
...
_14 = bs_create_bin `private_append`, `[8,{segment,1}]`, _6, `all`
which is not legal, as private_append on a literal will crash the
runtime system.
By inserting a bs_init_writable in front of bs_create_bin instructions
with a literal <<>> as the first fragment, and then using the freshly
created writable binary instead of the literal, the code sequence
becomes valid:
_1 = bs_init_writable `256`
_6 = bs_create_bin `private_append`, `[8,{segment,1}]`, _1, `all`
...
_14 = bs_create_bin `private_append`, `[8,{segment,1}]`, _6, `all`
Diffstat (limited to 'lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl')
-rw-r--r-- | lib/compiler/test/beam_ssa_check_SUITE_data/private_append.erl | 27 |
1 files changed, 26 insertions, 1 deletions
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 4d4b0f1bbd..c1edc54460 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 @@ -22,6 +22,8 @@ %% -module(private_append). +-feature(maybe_expr, enable). + -export([transformable0/1, transformable1/1, transformable1b/1, @@ -76,7 +78,9 @@ not_transformable14/0, not_transformable15/2, - id/1]). + id/1, + + bs_create_bin_on_literal/0]). %% Trivial smoke test transformable0(L) -> @@ -977,3 +981,24 @@ not_transformable15(_, V) -> id(I) -> I. + +%% Check that we don't try to private_append to something created by +%% bs_create_bin `append`, _, `<<>>`, ... +bs_create_bin_on_literal() -> +%ssa% () when post_ssa_opt -> +%ssa% X = bs_init_writable(_), +%ssa% Y = bs_create_bin(private_append, _, X, ...), +%ssa% Z = bs_create_bin(private_append, _, Y, ...), +%ssa% ret(Z). + << + << + (maybe + 2147483647 ?= ok + else + <<_>> -> + ok; + _ -> + <<>> + end)/bytes + >>/binary + >>. |