diff --git a/lib/compiler/src/beam_ssa_alias.erl b/lib/compiler/src/beam_ssa_alias.erl index c16011ebc66d..ec137f0ca80f 100644 --- a/lib/compiler/src/beam_ssa_alias.erl +++ b/lib/compiler/src/beam_ssa_alias.erl @@ -740,6 +740,11 @@ aa_bif(Dst, tl, Args, SS, AAS) -> %% TODO: Ignored for now, as we don't track what's inside maps. %% aa_bif(_Dst, map_get, _Args, SS, _AAS) -> %% SS; +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 5375298493e3..6bbbac7b30bb 100644 --- a/lib/compiler/test/beam_ssa_check_SUITE_data/alias.erl +++ b/lib/compiler/test/beam_ssa_check_SUITE_data/alias.erl @@ -65,7 +65,8 @@ stacktrace1/0, in_cons/0, make_fun/0, - gh6925/0]). + gh6925/0, + binary_part_aliases/2]). %% Trivial smoke test transformable0(L) -> @@ -672,3 +673,13 @@ gh6925() -> A = << <<"x">> || true >>, B = <>, {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). + +