File 0751-erts-Fix-matchspec-stack-depth-estimation-bug.patch of Package erlang

From e036714975e7b2d199b17b48007aa3a5f0e9dc0a Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Wed, 5 May 2021 21:40:18 +0200
Subject: [PATCH] erts: Fix matchspec stack depth estimation bug

---
 erts/emulator/beam/erl_db_util.c | 27 +++++++++++++++++++++++++--
 lib/stdlib/test/ets_SUITE.erl    | 14 +++++++++++++-
 2 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index e2c029c244..49518012e4 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -3765,6 +3765,7 @@ dmc_array(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(UWord) *text,
 {
     int all_constant = 1;
     int textpos = DMC_STACK_NUM(*text);
+    int preventive_bumps = 0;
     Uint i;
 
     /*
@@ -3784,13 +3785,35 @@ dmc_array(DMCContext *context, DMCHeap *heap, DMC_STACK_TYPE(UWord) *text,
         if (!c && all_constant) {
             all_constant = 0;
             if (i < nelems - 1) {
+                /* Revert preventive stack bumps as they will now be done again
+                 * for real by do_emit_constant() */
+                context->stack_used -= preventive_bumps;
+
                 dmc_rearrange_constants(context, text, textpos,
                                         p + i + 1, nelems - i - 1);
             }
-        } else if (c && !all_constant) {
-            do_emit_constant(context, text, p[i]);
+        } else if (c) {
+            if (all_constant) {
+                /*
+                 * OTP-17379:
+                 * All constants so far, but do preventive stack bumps
+                 * as the constants may later be converted to matchPushC
+                 * by dmc_rearrange_constants above.
+                 * Otherwise dmc_expr() may do incorrect stack depth estimation
+                 * when it emits instructions for the first non-constant.
+                 */
+                ++context->stack_used;
+                ++preventive_bumps;
+            }
+            else {
+                do_emit_constant(context, text, p[i]);
+            }
         }
     }
+    if (all_constant) {
+        /* Preventive stack bumps not needed */
+        context->stack_used -= preventive_bumps;
+    }
     *constant = all_constant;
     return retOk;
 }
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index 433b812fd5..2b8d6806ba 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -41,7 +41,9 @@
 -export([foldl_ordered/1, foldr_ordered/1, foldl/1, foldr/1, fold_empty/1]).
 -export([t_delete_object/1, t_init_table/1, t_whitebox/1, 
 	 t_delete_all_objects/1, t_insert_list/1, t_test_ms/1,
-	 t_select_delete/1,t_ets_dets/1]).
+	 t_select_delete/1,
+         t_select_pam_stack_overflow_bug/1,
+         t_ets_dets/1]).
 
 -export([do_lookup/2, do_lookup_element/3]).
 
@@ -145,8 +147,9 @@ all() ->
      update_counter_table_growth,
      match_heavy, {group, fold}, member, t_delete_object,
      t_init_table, t_whitebox, t_delete_all_objects,
-     t_insert_list, t_test_ms, t_select_delete, t_ets_dets,
-     memory, t_select_reverse, t_bucket_disappears,
+     t_insert_list, t_test_ms, t_select_delete,
+     t_select_pam_stack_overflow_bug,
+     t_ets_dets, memory, t_select_reverse, t_bucket_disappears,
      select_fail, t_insert_new, t_repair_continuation,
      otp_5340, otp_6338, otp_6842_select_1000, otp_7665,
      otp_8732, meta_wb, grow_shrink, grow_pseudo_deleted,
@@ -1267,6 +1270,15 @@ t_select_replace_next_bug(Config) when is_list(Config) ->
     lists:foreach(fun(Tab) -> ets:delete(Tab) end,Tables),
     ?line verify_etsmem(EtsMem).
 
+%% OTP-17379
+t_select_pam_stack_overflow_bug(Config) ->
+    T = ets:new(k, []),
+    ets:insert(T,[{x,17}]),
+    [{x,18}] = ets:select(T,[{{x,17}, [], [{{{element,1,'$_'},{const,18}}}]}]),
+    ets:delete(T),
+    ok.
+
+
 partly_bound(doc) ->
     ["Test that partly bound keys gives faster matches"];
 partly_bound(suite) ->
-- 
2.26.2

openSUSE Build Service is sponsored by