diff options
author | Björn Gustavsson <bjorn@erlang.org> | 2020-02-23 17:43:56 +0100 |
---|---|---|
committer | Björn Gustavsson <bjorn@erlang.org> | 2020-03-04 05:58:42 +0100 |
commit | 9ed20ba3b97b2c621494da0368d3570a9d0e5ffe (patch) | |
tree | 41b0ceb628abfbc5747851e19684465fbcb3fb0b | |
parent | 4de2b67cadc5f1433076f900579cc61b44c35909 (diff) | |
download | erlang-9ed20ba3b97b2c621494da0368d3570a9d0e5ffe.tar.gz |
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.)
-rw-r--r-- | lib/compiler/src/v3_core.erl | 23 | ||||
-rw-r--r-- | 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 @@ -343,6 +343,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()), %% Size exceeds length of binary. 'native' is redundant for %% binaries, but when it was present sys_core_fold would not @@ -352,6 +353,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), |