File 0434-v3_core-Fix-compiler-crash-when-compiling-failing-bi.patch of Package erlang
From 9ed20ba3b97b2c621494da0368d3570a9d0e5ffe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Sun, 23 Feb 2020 17:43:56 +0100
Subject: [PATCH] v3_core: Fix compiler crash when compiling failing binary
construction
The compiler would crash when compiling code such as the following
because the binding of `Var` was not done because the binary
construction would always fail:
case <<(Var = 1),[]/utf32>> of
_ when Var -> true
end.
(Also see 0f53ac61d9ce.)
---
lib/compiler/src/v3_core.erl | 23 ++++++++++++++++++-----
lib/compiler/test/bs_construct_SUITE.erl | 6 ++++++
2 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index 6a93f30f81..e38cfcbaa7 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -1144,11 +1144,24 @@ make_combined(Line, Val, Size) ->
{integer,Line,Size},
[integer,{unit,1},unsigned,big]}.
-expr_bin_1(Es, St) ->
- foldr(fun (E, {Ces,Esp,St0}) ->
- {Ce,Ep,St1} = bitstr(E, St0),
- {[Ce|Ces],Ep ++ Esp,St1}
- end, {[],[],St}, Es).
+expr_bin_1(Es, St0) ->
+ Res = foldr(fun (E, {Ces,Eps0,S0}) ->
+ try bitstr(E, S0) of
+ {Ce,Eps,S1} when is_list(Ces) ->
+ {[Ce|Ces],Eps ++ Eps0,S1};
+ {_Ce,Eps,S1} ->
+ {Ces,Eps ++ Eps0,S1}
+ catch
+ {bad_binary,Eps,S1} ->
+ {bad_binary,Eps ++ Eps0,S1}
+ end
+ end, {[],[],St0}, Es),
+ case Res of
+ {bad_binary,Eps,St} ->
+ throw({bad_binary,Eps,St});
+ {_,_,_}=Res ->
+ Res
+ end.
bitstr({bin_element,_,E0,Size0,[Type,{unit,Unit}|Flags]}, St0) ->
{E1,Eps0,St1} = safe(E0, St0),
diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl
index f428c3a27f..9df5f4aa0c 100644
--- a/lib/compiler/test/bs_construct_SUITE.erl
+++ b/lib/compiler/test/bs_construct_SUITE.erl
@@ -322,6 +322,7 @@ fail(Config) when is_list(Config) ->
end),
{'EXIT',{badarg,_}} = (catch <<13:(put(?FUNCTION_NAME, 17))>>),
17 = erase(?FUNCTION_NAME),
+ {'EXIT',{badarg,_}} = (catch fail_1()),
ok.
@@ -325,6 +326,11 @@ fail(Config) when is_list(Config) ->
ok.
+fail_1() ->
+ case <<(V0 = 1),[]/utf32>> of
+ _ when V0 -> true
+ end.
+
float_bin(Config) when is_list(Config) ->
%% Some more coverage.
{<<1,2,3>>,7.0} = float_bin_1(4),
--
2.16.4