File 0190-beam_ssa_opt-Don-t-optimize-constants-larger-than-1-.patch of Package erlang
From d8a23287b45b74e7c01dd9bd358d0a2fec3ef2ce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20H=C3=B6gberg?= <john@erlang.org>
Date: Mon, 9 Jan 2023 10:31:35 +0100
Subject: [PATCH] beam_ssa_opt: Don't optimize constants larger than 1<<24 bits
---
lib/compiler/src/beam_ssa_opt.erl | 16 +++++++++-------
lib/compiler/test/bs_construct_SUITE.erl | 5 +++++
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl
index fecb5bebd5..435c6773f3 100644
--- a/lib/compiler/src/beam_ssa_opt.erl
+++ b/lib/compiler/src/beam_ssa_opt.erl
@@ -2100,18 +2100,20 @@ opt_create_bin_arg(Type, Unit, Flags, #b_literal{val=Val}, #b_literal{val=Size})
when is_integer(Size), is_integer(Unit) ->
EffectiveSize = Size * Unit,
if
- EffectiveSize > 0 ->
+ EffectiveSize > (1 bsl 24) ->
+ %% Don't bother converting really huge segments as they might fail
+ %% with a `system_limit` exception in runtime. Keeping them as-is
+ %% ensures that the extended error information will be accurate.
+ %%
+ %% We'll also reduce the risk of crashing with an unhelpful "out of
+ %% memory" error message during compilation.
+ not_possible;
+ EffectiveSize > 0, EffectiveSize =< (1 bsl 24) ->
case {Type,opt_create_bin_endian(Flags)} of
{integer,big} when is_integer(Val) ->
if
EffectiveSize < 64 ->
[<<Val:EffectiveSize>>];
- EffectiveSize > 1 bsl 24 ->
- %% The binary construction could fail with a
- %% system_limit. Don't optimize to ensure that
- %% the extended error information will be
- %% accurate.
- not_possible;
true ->
opt_bs_put_split_int(Val, EffectiveSize)
end;
diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl
index cecc3660d4..93cee3c189 100644
--- a/lib/compiler/test/bs_construct_SUITE.erl
+++ b/lib/compiler/test/bs_construct_SUITE.erl
@@ -522,6 +522,11 @@ nasty_literals(Config) when is_list(Config) ->
I = 16#7777FFFF7777FFFF7777FFFF7777FFFF7777FFFF7777FFFF,
id(<<I:260>>),
+ %% GH-6643: Excessively large literals could cause the compiler to run out
+ %% of memory.
+ catch id(<<0:16777216/big-integer-unit:1>>),
+ catch id(<<0:(16777216*2)/big-integer-unit:1>>),
+
ok.
-define(COF(Int0),
--
2.35.3