File 0118-compiler-bif-binary_part-2-3-should-alias-its-argume.patch of Package erlang
From 1dd55c4c494ca50f05ba88746424699f669d9419 Mon Sep 17 00:00:00 2001
From: Frej Drejhammar <frej.drejhammar@gmail.com>
Date: Mon, 22 May 2023 16:06:53 +0200
Subject: [PATCH] compiler: bif:binary_part/{2,3} should alias its arguments
The `bif:binary_part/{2,3}` is a guard bif which creates a
sub-binary (containing a reference to its argument) from its argument,
thus aliasing both. Currently this does not produce any errors as the
BEAM will only ever append to binaries, but if we ever attempt to do
destructive updates of binaries this will give us grief, so we'd
better correct it.
---
lib/compiler/src/beam_ssa_alias.erl | 5 +++++
.../test/beam_ssa_check_SUITE_data/alias.erl | 13 ++++++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/lib/compiler/src/beam_ssa_alias.erl b/lib/compiler/src/beam_ssa_alias.erl
index c16011ebc6..ec137f0ca8 100644
--- a/lib/compiler/src/beam_ssa_alias.erl
+++ b/lib/compiler/src/beam_ssa_alias.erl
@@ -1177,6 +1177,11 @@ aa_bif(Dst, tl, Args, SS, AAS) ->
aa_pair_extraction(Dst, Pair, tl, SS);
aa_bif(Dst, map_get, [_Key,Map], SS, AAS) ->
aa_map_extraction(Dst, Map, SS, AAS);
+aa_bif(Dst, binary_part, Args, SS, _AAS) ->
+ %% bif:binary_part/{2,3} is the only guard bif which could lead to
+ %% aliasing, it extracts a sub-binary with a reference to its
+ %% argument.
+ aa_set_aliased([Dst|Args], SS);
aa_bif(Dst, Bif, Args, SS, _AAS) ->
Arity = length(Args),
case erl_internal:guard_bif(Bif, Arity)
diff --git a/lib/compiler/test/beam_ssa_check_SUITE_data/alias.erl b/lib/compiler/test/beam_ssa_check_SUITE_data/alias.erl
index 5375298493..6bbbac7b30 100644
--- a/lib/compiler/test/beam_ssa_check_SUITE_data/alias.erl
+++ b/lib/compiler/test/beam_ssa_check_SUITE_data/alias.erl
@@ -67,6 +67,7 @@
in_cons/0,
make_fun/0,
gh6925/0,
+ binary_part_aliases/2]).
aliased_map_lookup_bif/1,
aliased_map_lookup_instr/1,
aliased_tuple_element_bif/1,
@@ -691,6 +692,14 @@ gh6925() ->
B = <<A/binary, "z">>,
{A, B}.
+%% Check that bif:binary_part/3 is correctly flagged as an operation
+%% which aliases its operands
+binary_part_aliases(A, B) ->
+%ssa% (_,_) when post_ssa_opt ->
+%ssa% X = bif:binary_part(_, _, _),
+%ssa% ret(X) {aliased => [X]}.
+ binary_part(<<>>, A, B).
+
%% Check that as the map is aliased, the extracted value should also
%% be aliased.
aliased_map_lookup_bif(M) ->
--
2.35.3