File 2651-Remove-unreachable-bs_put-instructions.patch of Package erlang

From 5ffbf569c3817cb09ca4780802eddc7c7319f354 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Wed, 17 Jun 2020 10:22:58 +0200
Subject: [PATCH] Remove unreachable bs_put* instructions

bs_put* instructions with invalid sizes used to be converted to badarg
instructions. This is unnecessary, since bs_add or bs_init* will raise
an exception if the size is invalid. Therefore, if the size for a
bs_put* instruction is invalid, simply remove the instruction.
---
 erts/emulator/beam/generators.tab | 24 ++++++++++++++++++------
 erts/emulator/beam/instrs.tab     |  6 ------
 erts/emulator/beam/ops.tab        | 14 +++++++-------
 3 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/erts/emulator/beam/generators.tab b/erts/emulator/beam/generators.tab
index c3e30d6840..49afb3a6b1 100644
--- a/erts/emulator/beam/generators.tab
+++ b/erts/emulator/beam/generators.tab
@@ -270,8 +270,12 @@ gen.put_binary(Fail, Size, Unit, Flags, Src) {
             op->a[2] = Src;
         } else {
         error:
-            $BeamOpNameArity(op, badarg, 1);
-            op->a[0] = Fail;
+            /*
+             * Invalid size. This instruction can't possibly be
+             * reached, because bs_add or bs_init* would already
+             * have raised a system_limit exception.
+             */
+            $BeamOpNameArity(op, delete_me, 0);
         }
     } else if (Size.type == TAG_q) {
 #ifdef ARCH_64
@@ -316,8 +320,12 @@ gen.put_integer(Fail, Size, Unit, Flags, Src) {
         Uint size;
         if (!beam_load_safe_mul(Size.val, Unit.val, &size)) {
         error:
-            $BeamOpNameArity(op, badarg, 1);
-            op->a[0] = Fail;
+            /*
+             * Invalid size. This instruction can't possibly be
+             * reached, because bs_add or bs_init* would already
+             * have raised a system_limit exception.
+             */
+            $BeamOpNameArity(op, delete_me, 0);
             return op;
         }
         $BeamOpNameArity(op, i_new_bs_put_integer_imm, 4);
@@ -364,8 +372,12 @@ gen.put_float(Fail, Size, Unit, Flags, Src) {
         op->a[0] = Fail;
         op->a[1].type = TAG_u;
         if (!beam_load_safe_mul(Size.val, Unit.val, &op->a[1].val)) {
-            $BeamOpNameArity(op, badarg, 1);
-            op->a[0] = Fail;
+            /*
+             * Size overflow. This instruction can't possibly be reached, because
+             * bs_add or bs_init* would already have raised a system_limit
+             * exception.
+             */
+            $BeamOpNameArity(op, delete_me, 0);
         } else {
             op->a[2] = Flags;
             op->a[3] = Src;
diff --git a/erts/emulator/beam/instrs.tab b/erts/emulator/beam/instrs.tab
index 697c777825..a9e1dd1bfe 100644
--- a/erts/emulator/beam/instrs.tab
+++ b/erts/emulator/beam/instrs.tab
@@ -1035,12 +1035,6 @@ is_ge_literal(Fail, X, Y) {
     CMP_GE_LITERAL_ACTION($X, $Y, $FAIL($Fail));
 }
 
-badarg_body() {
-    c_p->freason = BADARG;
-    $FAIL_BODY();
-    //| -no_next;
-}
-
 badmatch(Src) {
     c_p->fvalue = $Src;
     c_p->freason = BADMATCH;
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index 49bd7a128c..e676cd0e67 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -261,12 +261,9 @@ raise Trace Value => move Trace x | move Value x=1 | move x x=2 | i_raise
 
 i_raise
 
-# Internal now, but could be useful to make known to the compiler.
-badarg/1
-badarg p => badarg_body
-badarg Fail=f => jump Fail
-
-badarg_body
+# Workaround the limitation that generators must always return at least one instruction.
+delete_me/0
+delete_me =>
 
 system_limit/1
 system_limit p => system_limit_body
@@ -1392,7 +1389,10 @@ i_bs_validate_unicode Fail Src=c => move Src x | i_bs_validate_unicode Fail x
 #
 # Storing floats into binaries.
 #
-bs_put_float Fail Sz=q Unit Flags Val => badarg Fail
+
+# Will fail. No need to keep the instruction, because bs_add or
+# bs_init* would already have raised an exception.
+bs_put_float Fail Sz=q Unit Flags Val =>
 
 bs_put_float Fail=j Sz=s Unit=u Flags=u Src=s => \
 			put_float(Fail, Sz, Unit, Flags, Src)
-- 
2.26.2

openSUSE Build Service is sponsored by