File 6661-erts-Support-missing-guard-BIFs-like-is_boolean-1-in.patch of Package erlang

From 1b78756047c2b7a1c55e58ba19dce60e65fd29da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20H=C3=B6gberg?= <john@erlang.org>
Date: Thu, 23 Mar 2023 09:14:37 +0100
Subject: [PATCH] erts: Support missing guard BIFs like is_boolean/1 in match
 specs

---
 erts/doc/src/match_spec.xml             | 38 +++++++++-------
 erts/emulator/beam/erl_db_util.c        | 60 ++++++++++++++++++++-----
 erts/emulator/test/match_spec_SUITE.erl | 37 +++++++++++++--
 3 files changed, 104 insertions(+), 31 deletions(-)

diff --git a/erts/doc/src/match_spec.xml b/erts/doc/src/match_spec.xml
index 81b30efec8..a62eef43c4 100644
--- a/erts/doc/src/match_spec.xml
+++ b/erts/doc/src/match_spec.xml
@@ -87,7 +87,8 @@
         <c><![CDATA[is_pid]]></c> | <c><![CDATA[is_port]]></c> |
         <c><![CDATA[is_reference]]></c> | <c><![CDATA[is_tuple]]></c> |
         <c><![CDATA[is_map]]></c> | <c><![CDATA[is_map_key]]></c> |
-        <c><![CDATA[is_binary]]></c> | <c><![CDATA[is_function]]></c> |
+        <c><![CDATA[is_binary]]></c> | <c><![CDATA[is_bitstring]]></c> |
+        <c><![CDATA[is_boolean]]></c> | <c><![CDATA[is_function]]></c> |
         <c><![CDATA[is_record]]></c> | <c><![CDATA[is_seq_trace]]></c> |
         <c><![CDATA['and']]></c> | <c><![CDATA['or']]></c> |
         <c><![CDATA['not']]></c> | <c><![CDATA['xor']]></c> |
@@ -113,11 +114,12 @@
         <c><![CDATA[length]]></c> | <c><![CDATA[map_get]]></c> |
         <c><![CDATA[map_size]]></c> |
         <c><![CDATA[max]]></c> | <c><![CDATA[min]]></c> |
-        <c><![CDATA[node]]></c> |
-        <c><![CDATA[round]]></c> | <c><![CDATA[size]]></c> |
+        <c><![CDATA[node]]></c> | <c><![CDATA[float]]></c> |
+        <c><![CDATA[round]]></c> | <c><![CDATA[floor]]></c> |
+        <c><![CDATA[ceil]]></c> | <c><![CDATA[size]]></c> |
         <c><![CDATA[bit_size]]></c> | <c><![CDATA[byte_size]]></c> |
-        <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> |
-        <c><![CDATA[binary_part]]></c> |
+        <c><![CDATA[tuple_size]]></c> | <c><![CDATA[tl]]></c> |
+        <c><![CDATA[trunc]]></c> | <c><![CDATA[binary_part]]></c> |
         <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> |
         <c><![CDATA['*']]></c> | <c><![CDATA['div']]></c> |
         <c><![CDATA['rem']]></c> | <c><![CDATA['band']]></c> |
@@ -173,8 +175,9 @@
         <c><![CDATA[is_list]]></c> | <c><![CDATA[is_number]]></c> |
         <c><![CDATA[is_pid]]></c> | <c><![CDATA[is_port]]></c> |
         <c><![CDATA[is_reference]]></c> | <c><![CDATA[is_tuple]]></c> |
-        <c><![CDATA[is_map]]></c> | <c><![CDATA[map_is_key]]></c> |
-        <c><![CDATA[is_binary]]></c> | <c><![CDATA[is_function]]></c> |
+        <c><![CDATA[is_map]]></c> | <c><![CDATA[is_map_key]]></c> |
+        <c><![CDATA[is_binary]]></c> | <c><![CDATA[is_bitstring]]></c> |
+        <c><![CDATA[is_boolean]]></c> | <c><![CDATA[is_function]]></c> |
         <c><![CDATA[is_record]]></c> | <c><![CDATA['and']]></c> |
         <c><![CDATA['or']]></c> | <c><![CDATA['not']]></c> |
         <c><![CDATA['xor']]></c> | <c><![CDATA['andalso']]></c> |
@@ -199,11 +202,12 @@
         <c><![CDATA[length]]></c> | <c><![CDATA[map_get]]></c> |
         <c><![CDATA[map_size]]></c> |
         <c><![CDATA[max]]></c> | <c><![CDATA[min]]></c> |
-        <c><![CDATA[node]]></c> |
-        <c><![CDATA[round]]></c> | <c><![CDATA[size]]></c> |
+        <c><![CDATA[node]]></c> | <c><![CDATA[float]]></c> |
+        <c><![CDATA[round]]></c> | <c><![CDATA[floor]]></c> |
+        <c><![CDATA[ceil]]></c> | <c><![CDATA[size]]></c> |
         <c><![CDATA[bit_size]]></c> | <c><![CDATA[byte_size]]></c> |
-        <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> |
-        <c><![CDATA[binary_part]]></c> |
+        <c><![CDATA[tuple_size]]></c> | <c><![CDATA[tl]]></c> |
+        <c><![CDATA[trunc]]></c> | <c><![CDATA[binary_part]]></c> |
         <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> |
         <c><![CDATA['*']]></c> | <c><![CDATA['div']]></c> |
         <c><![CDATA['rem']]></c> | <c><![CDATA['band']]></c> |
@@ -228,9 +232,10 @@
         follows:</p>
 
       <taglist>
-        <tag><c>is_atom</c>, <c>is_float</c>, <c>is_integer</c>, <c>is_list</c>,
-          <c>is_number</c>, <c>is_pid</c>, <c>is_port</c>, <c>is_reference</c>,
-          <c>is_tuple</c>, <c>is_map</c>, <c>is_binary</c>, <c>is_function</c>
+        <tag><c>is_atom</c>, <c>is_boolean</c>, <c>is_float</c>,
+          <c>is_integer</c>, <c>is_list</c>, <c>is_number</c>, <c>is_pid</c>,
+          <c>is_port</c>, <c>is_reference</c>, <c>is_tuple</c>, <c>is_map</c>,
+          <c>is_binary</c>, <c>is_bitstring</c>, <c>is_function</c>
         </tag>
         <item>
           <p>Same as the corresponding guard tests in Erlang, return
@@ -281,8 +286,9 @@
         <tag><c>abs</c>, <c>element</c>, <c>hd</c>, <c>length</c>,
           <c>map_get</c>, <c>map_size</c>,
           <c>max</c>, <c>min</c>,
-          <c>node</c>, <c>round</c>,
-          <c>size</c>, <c>bit_size</c>, <c>byte_size</c>, <c>tl</c>,
+          <c>node</c>, <c>round</c>, <c>ceil</c>, <c>floor</c>, <c>float</c>,
+          <c>size</c>, <c>bit_size</c>, <c>byte_size</c>, <c>tuple_size</c>,
+          <c>tl</c>,
           <c>trunc</c>, <c>binary_part</c>, <c>'+'</c>,
           <c>'-'</c>, <c>'*'</c>, <c>'div'</c>, <c>'rem'</c>, <c>'band'</c>,
           <c>'bor'</c>, <c>'bxor'</c>, <c>'bnot'</c>, <c>'bsl'</c>,
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index 4290d8506f..38d755f7f6 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -589,16 +589,34 @@ static DMCGuardBif guard_tab[] =
 	DBIF_ALL
     },
     {
-	am_is_binary,
-	&is_binary_1,
-	1,
-	DBIF_ALL
+        am_is_binary,
+        &is_binary_1,
+        1,
+        DBIF_ALL
     },
     {
-	am_is_function,
-	&is_function_1,
-	1,
-	DBIF_ALL
+        am_is_bitstring,
+        &is_bitstring_1,
+        1,
+        DBIF_ALL
+    },
+    {
+        am_is_boolean,
+        &is_boolean_1,
+        1,
+        DBIF_ALL
+    },
+    {
+        am_is_function,
+        &is_function_1,
+        1,
+        DBIF_ALL
+    },
+    {
+        am_is_function,
+        &is_function_2,
+        2,
+        DBIF_ALL
     },
     {
 	am_is_record,
@@ -696,6 +714,12 @@ static DMCGuardBif guard_tab[] =
 	1,
 	DBIF_ALL
     },
+    {
+	am_tuple_size,
+	&tuple_size_1,
+	1,
+	DBIF_ALL
+    },
     {
 	am_binary_part,
 	&binary_part_2,
@@ -721,10 +745,22 @@ static DMCGuardBif guard_tab[] =
 	DBIF_ALL
     },
     {
-	am_float,
-	&float_1,
-	1,
-	DBIF_ALL
+        am_float,
+        &float_1,
+        1,
+        DBIF_ALL
+    },
+    {
+        am_ceil,
+        &ceil_1,
+        1,
+        DBIF_ALL
+    },
+    {
+        am_floor,
+        &floor_1,
+        1,
+        DBIF_ALL
     },
     {
 	am_Plus,
diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl
index 18df432836..43e475b125 100644
--- a/erts/emulator/test/match_spec_SUITE.erl
+++ b/erts/emulator/test/match_spec_SUITE.erl
@@ -28,7 +28,8 @@
 	 ms_trace2/1, ms_trace3/1, ms_trace_dead/1, boxed_and_small/1,
 	 destructive_in_test_bif/1, guard_exceptions/1,
 	 empty_list/1,
-	 unary_plus/1, unary_minus/1, moving_labels/1]).
+	 unary_plus/1, unary_minus/1, moving_labels/1,
+         guard_bifs/1]).
 -export([fpe/1]).
 -export([otp_9422/1]).
 -export([faulty_seq_trace/1, do_faulty_seq_trace/0]).
@@ -57,7 +58,8 @@ all() ->
      faulty_seq_trace,
      empty_list,
      otp_9422,
-     maps].
+     maps,
+     guard_bifs].
 
 init_per_testcase(_TestCase, Config) ->
     Config.
@@ -1145,7 +1147,36 @@ moving_labels(Config) when is_list(Config) ->
 	erlang:match_spec_test({true,false}, Ms2, table),
 
     ok.
-    
+
+-record(dummy_record, {}).
+
+%% GH-7045: Some guard BIFs were unavailable in match specifications.
+guard_bifs(_Config) ->
+    Matches =
+        [begin
+             BIF = list_to_tuple([F | lists:duplicate(A, '$1')]),
+             erlang:match_spec_test(Data, [{{'$1'}, [BIF], [{{'$1'}}]}], Kind)
+         end
+         || {F, A} <- erlang:module_info(functions),
+            {Data, Kind} <- [{{a}, table}, {[a], trace}],
+            F =/= is_record, %% Has special requirements, checked below.
+            erl_internal:arith_op(F, A) orelse
+                erl_internal:bool_op(F, A) orelse
+                erl_internal:comp_op(F, A) orelse
+                erl_internal:guard_bif(F, A)],
+    [] = [T || {error, _}=T <- Matches],
+
+    IsRecord = {is_record,
+                '$1',
+                dummy_record,
+                record_info(size, dummy_record)},
+    [{ok, _, [], []} =
+         erlang:match_spec_test(Data, [{{'$1'}, [IsRecord], [{{'$1'}}]}], Kind)
+     || {Data, Kind} <- [{{#dummy_record{}}, table},
+                         {[#dummy_record{}], trace}]],
+
+    ok.
+
 tr(Fun, MFA, Pat, Expected) ->
     tr(Fun, MFA, [call], Pat, [global], Expected).
 
-- 
2.35.3

openSUSE Build Service is sponsored by