File 0837-Fix-coercion-of-integer-literals-to-floats-in-binary.patch of Package erlang
From 760f425e6c5fd55f15b0029b39bb3213a5b4a89c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Wed, 26 Jan 2022 07:23:02 +0100
Subject: [PATCH] Fix coercion of integer literals to floats in binary matching
In both binary construction and matching, literal integer values
are allowed in float segments, and they are automatically coerced
to floats.
Thus, the compiler automatically rewrites code such as the following:
foo() ->
<<0/float-native>> = <<0/float-native>>.
to:
foo() ->
<<0.0/float-native>> = <<0.0/float-native>>.
However, if the order of `native` and `float` were switched like this:
bar() ->
<<0/native-float>> = <<0/native-float>>.
the compiler would fail to coerce the `0` in the binary pattern and would
end up with:
bar() ->
<<0/native-float>> = <<0.0/native-float>>.
which would obviously not match.
---
lib/compiler/src/v3_core.erl | 4 ++--
lib/compiler/test/bs_match_SUITE.erl | 10 ++++++++++
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 456e6f2c30..617b7e2df6 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1959,7 +1959,7 @@ pat_segment({bin_element,L,Val,Size0,Type0}, St) ->
[Type,{unit,Unit}|Flags] = Type1,
Anno = lineno_anno(L, St),
{Pval0,St1} = pattern(Val, St),
- Pval = coerce_to_float(Pval0, Type0),
+ Pval = coerce_to_float(Pval0, Type),
Size = erl_eval:partial_eval(Size1),
{Psize,St2} = exprs([Size], St1),
{#ibitstr{anno=#a{anno=Anno},
@@ -1968,7 +1968,7 @@ pat_segment({bin_element,L,Val,Size0,Type0}, St) ->
type=#c_literal{val=Type},
flags=#c_literal{val=Flags}},St2}.
-coerce_to_float(#c_literal{val=Int}=E, [float|_]) when is_integer(Int) ->
+coerce_to_float(#c_literal{val=Int}=E, float) when is_integer(Int) ->
try
E#c_literal{val=float(Int)}
catch
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 70c7bccf80..ce81856219 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -221,6 +221,16 @@ int_float(Config) when is_list(Config) ->
<<103133.0:64/float>> = <<103133:64/float>>,
<<103133:64/float>> = <<103133:64/float>>,
+ %% Must work with type and flags in either order.
+ NativeFortyTwo = id(<<42/native-float>>),
+ <<42/float-native>> = NativeFortyTwo,
+ <<42/native-float>> = NativeFortyTwo,
+
+ %% Must work with redundant flags.
+ SixtyFour = id(<<64/float>>),
+ <<64/unsigned-float>> = SixtyFour,
+ <<64/float-unsigned>> = SixtyFour,
+
%% Coverage of error cases in sys_pre_expand:coerce_to_float/2.
case id(default) of
<<(1 bsl 1024):64/float>> ->
--
2.34.1