From 0bb261b730eff06cca524ea9999ff035585ef5b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Fri, 28 Sep 2018 05:57:47 +0200 Subject: Fix rare bug in binary matching (again) 2e40d8d1c51a attempted fix a bug in binary matching, but it only fixed the bug for the minimized test case. This commit removes the previous fix and fixes the bug in a more effective way. See the comments in the new code in `sys_core_bsm` for an explanation. This commit restores the optimizations in string.erl and dets_v9.erl that the previous fix disabled. I have not found any code where this commit will disable optimizations when they are actually safe. There are some changes to the code in ssl_cipher.erl in that some bs_start_match2 instruction did not reuse the binary register for the match context, but the delayed sub binary optimizations was never applied to the code in the first place. https://bugs.erlang.org/browse/ERL-689 --- lib/compiler/test/bs_match_SUITE.erl | 38 +++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'lib/compiler/test/bs_match_SUITE.erl') diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl index 7814738449..e97dbac8a6 100644 --- a/lib/compiler/test/bs_match_SUITE.erl +++ b/lib/compiler/test/bs_match_SUITE.erl @@ -1690,30 +1690,62 @@ non_opt_eq([], <<>>) -> %% ERL-689 -erl_689(Config) -> +erl_689(_Config) -> {{0, 0, 0}, <<>>} = do_erl_689_1(<<0>>, ?MODULE), {{2018, 8, 7}, <<>>} = do_erl_689_1(<<4,2018:16/little,8,7>>, ?MODULE), {{0, 0, 0}, <<>>} = do_erl_689_2(?MODULE, <<0>>), {{2018, 8, 7}, <<>>} = do_erl_689_2(?MODULE, <<4,2018:16/little,8,7>>), ok. -do_erl_689_1(<>, _) -> +do_erl_689_1(Arg1, Arg2) -> + Res = do_erl_689_1a(Arg1, Arg2), + Res = do_erl_689_1b(Arg1, Arg2). + +do_erl_689_2(Arg1, Arg2) -> + Res = do_erl_689_2a(Arg1, Arg2), + Res = do_erl_689_2b(Arg1, Arg2). + +do_erl_689_1a(<>, _) -> + case {Data, Length} of + {_, 0} -> + %% bs_context_to_binary would incorrectly set Data to the original + %% binary (before matching in the function head). + {{0, 0, 0}, Data}; + {<>, 4} -> + {{Y, M, D}, Rest} + end. + +do_erl_689_1b(<>, _) -> case {Data, Length} of {_, 0} -> %% bs_context_to_binary would incorrectly set Data to the original %% binary (before matching in the function head). + id(0), {{0, 0, 0}, Data}; {<>, 4} -> + id(1), + {{Y, M, D}, Rest} + end. + +do_erl_689_2a(_, <>) -> + case {Length, Data} of + {0, _} -> + %% bs_context_to_binary would incorrectly set Data to the original + %% binary (before matching in the function head). + {{0, 0, 0}, Data}; + {4, <>} -> {{Y, M, D}, Rest} end. -do_erl_689_2(_, <>) -> +do_erl_689_2b(_, <>) -> case {Length, Data} of {0, _} -> %% bs_context_to_binary would incorrectly set Data to the original %% binary (before matching in the function head). + id(0), {{0, 0, 0}, Data}; {4, <>} -> + id(1), {{Y, M, D}, Rest} end. -- cgit v1.2.3