diff options
-rw-r--r-- | CONTRIBUTING.md | 1 | ||||
-rw-r--r-- | erts/emulator/beam/ops.tab | 2 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_sys_common_misc.c | 3 | ||||
-rw-r--r-- | erts/emulator/test/num_bif_SUITE.erl | 1 | ||||
-rw-r--r-- | lib/compiler/src/v3_core.erl | 19 | ||||
-rw-r--r-- | lib/crypto/c_src/otp_test_engine.c | 3 | ||||
-rw-r--r-- | lib/dialyzer/test/small_SUITE_data/results/left_assoc | 2 | ||||
-rw-r--r-- | lib/dialyzer/test/small_SUITE_data/src/left_assoc.erl | 96 | ||||
-rw-r--r-- | lib/erl_interface/src/legacy/erl_marshal.c | 2 | ||||
-rw-r--r-- | lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c | 12 | ||||
-rw-r--r-- | lib/stdlib/src/ms_transform.erl | 6 |
11 files changed, 139 insertions, 8 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 96db464b52..8814e506f9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,6 +3,7 @@ ## License By making a contribution to this project, I certify that: + (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab index 5942a7e6bf..d71594235e 100644 --- a/erts/emulator/beam/ops.tab +++ b/erts/emulator/beam/ops.tab @@ -244,7 +244,7 @@ if_end # Optimize for that case. raise x==2 x==1 => i_raise raise Trace=y Value=y => move Trace x=2 | move Value x=1 | i_raise -raise Trace Value => move Trace x=3 | move Value x=1 | move x=3 x=2 | i_raise +raise Trace Value => move Trace x | move Value x=1 | move x x=2 | i_raise i_raise diff --git a/erts/emulator/sys/common/erl_sys_common_misc.c b/erts/emulator/sys/common/erl_sys_common_misc.c index 2541ab5d31..d34e1a9ec0 100644 --- a/erts/emulator/sys/common/erl_sys_common_misc.c +++ b/erts/emulator/sys/common/erl_sys_common_misc.c @@ -176,6 +176,7 @@ sys_double_to_chars_fast(double f, char *buffer, int buffer_size, int decimals, double af; Uint64 int_part, frac_part; int neg; + int has_decimals = decimals != 0; char *p = buffer; if (decimals < 0) @@ -257,7 +258,7 @@ sys_double_to_chars_fast(double f, char *buffer, int buffer_size, int decimals, } /* Delete trailing zeroes */ - if (compact) + if (compact && has_decimals) p = find_first_trailing_zero(p); *p = '\0'; return p - buffer; diff --git a/erts/emulator/test/num_bif_SUITE.erl b/erts/emulator/test/num_bif_SUITE.erl index 700734cd0b..f15217814a 100644 --- a/erts/emulator/test/num_bif_SUITE.erl +++ b/erts/emulator/test/num_bif_SUITE.erl @@ -161,6 +161,7 @@ t_float_to_string(Config) when is_list(Config) -> test_fts("1.000",1.0, [{decimals, 3}]), test_fts("1.0",1.0, [{decimals, 1}]), test_fts("1.0",1.0, [{decimals, 3}, compact]), + test_fts("10",10.0, [{decimals, 0}, compact]), test_fts("1.12",1.123, [{decimals, 2}]), test_fts("1.123",1.123, [{decimals, 3}]), test_fts("1.123",1.123, [{decimals, 3}, compact]), diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 5aaf5bfd51..45e0ed5088 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -329,14 +329,16 @@ gexpr({protect,Line,Arg}, Bools0, St0) -> Anno = lineno_anno(Line, St), {#iprotect{anno=#a{anno=Anno},body=Eps++[E]},[],Bools0,St} end; -gexpr({op,L,'andalso',E1,E2}, Bools, St0) -> +gexpr({op,_,'andalso',_,_}=E0, Bools, St0) -> + {op,L,'andalso',E1,E2} = right_assoc(E0, 'andalso', St0), Anno = lineno_anno(L, St0), {#c_var{name=V0},St} = new_var(Anno, St0), V = {var,L,V0}, False = {atom,L,false}, E = make_bool_switch_guard(L, E1, V, E2, False), gexpr(E, Bools, St); -gexpr({op,L,'orelse',E1,E2}, Bools, St0) -> +gexpr({op,_,'orelse',_,_}=E0, Bools, St0) -> + {op,L,'orelse',E1,E2} = right_assoc(E0, 'orelse', St0), Anno = lineno_anno(L, St0), {#c_var{name=V0},St} = new_var(Anno, St0), V = {var,L,V0}, @@ -2055,6 +2057,19 @@ fail_clause(Pats, Anno, Arg) -> body=[#iprimop{anno=#a{anno=Anno},name=#c_literal{val=match_fail}, args=[Arg]}]}. +%% Optimization for Dialyzer. +right_assoc(E, Op, St) -> + case member(dialyzer, St#core.opts) of + true -> + right_assoc2(E, Op); + false -> + E + end. + +right_assoc2({op,L1,Op,{op,L2,Op,E1,E2},E3}, Op) -> + right_assoc2({op,L2,Op,E1,{op,L1,Op,E2,E3}}, Op); +right_assoc2(E, _Op) -> E. + annotate_tuple(A, Es, St) -> case member(dialyzer, St#core.opts) of true -> diff --git a/lib/crypto/c_src/otp_test_engine.c b/lib/crypto/c_src/otp_test_engine.c index b6c9067964..34c825059f 100644 --- a/lib/crypto/c_src/otp_test_engine.c +++ b/lib/crypto/c_src/otp_test_engine.c @@ -64,7 +64,8 @@ static int test_init(ENGINE *e) { printf("OTP Test Engine Initializatzion!\r\n"); /* Load all digest and cipher algorithms. Needed for password protected private keys */ - OpenSSL_add_all_algorithms(); + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); return 111; } diff --git a/lib/dialyzer/test/small_SUITE_data/results/left_assoc b/lib/dialyzer/test/small_SUITE_data/results/left_assoc new file mode 100644 index 0000000000..58cdad29de --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/results/left_assoc @@ -0,0 +1,2 @@ + +left_assoc.erl:93: The variable __@2 can never match since previous clauses completely covered the type binary() diff --git a/lib/dialyzer/test/small_SUITE_data/src/left_assoc.erl b/lib/dialyzer/test/small_SUITE_data/src/left_assoc.erl new file mode 100644 index 0000000000..0250e4ab49 --- /dev/null +++ b/lib/dialyzer/test/small_SUITE_data/src/left_assoc.erl @@ -0,0 +1,96 @@ +-module(left_assoc). + +%% As pointed out in ERL-680, analyzing guards with short circuit +%% operators becomes very slow as the number of left associations +%% grows. + +-spec from_iso8601('Elixir.String':t(), 'Elixir.Calendar':calendar()) -> + {ok, t()} | {error, atom()}. + +-export_type([t/0]). + +-type t() :: + #{'__struct__' := 'Elixir.Date', + calendar := 'Elixir.Calendar':calendar(), + day := 'Elixir.Calendar':day(), + month := 'Elixir.Calendar':month(), + year := 'Elixir.Calendar':year()}. + +-export([from_iso8601/1, + from_iso8601/2]). + +from_iso8601(__@1) -> + from_iso8601(__@1, 'Elixir.Calendar.ISO'). + +from_iso8601(<<45/integer,_rest@1/binary>>, _calendar@1) -> + case raw_from_iso8601(_rest@1, _calendar@1) of + {ok,#{year := _year@1} = _date@1} -> + {ok,_date@1#{year := - _year@1}}; + __@1 -> + __@1 + end; +from_iso8601(<<_rest@1/binary>>, _calendar@1) -> + raw_from_iso8601(_rest@1, _calendar@1). + +raw_from_iso8601(_string@1, _calendar@1) -> + case _string@1 of + <<_y1@1/integer, + _y2@1/integer, + _y3@1/integer, + _y4@1/integer, + 45/integer, + _m1@1/integer, + _m2@1/integer, + 45/integer, + _d1@1/integer, + _d2@1/integer>> + when + ((((((((((((((_y1@1 >= 48 + andalso + _y1@1 =< 57) + andalso + _y2@1 >= 48) + andalso + _y2@1 =< 57) + andalso + _y3@1 >= 48) + andalso + _y3@1 =< 57) + andalso + _y4@1 >= 48) + andalso + _y4@1 =< 57) + andalso + _m1@1 >= 48) + andalso + _m1@1 =< 57) + andalso + _m2@1 >= 48) + andalso + _m2@1 =< 57) + andalso + _d1@1 >= 48) + andalso + _d1@1 =< 57) + andalso + _d2@1 >= 48) + andalso + _d2@1 =< 57 -> + {ok, + #{year => (_y1@1 - 48) * 1000 + (_y2@1 - 48) * 100 + + + (_y3@1 - 48) * 10 + + + (_y4@1 - 48), + month => (_m1@1 - 48) * 10 + (_m2@1 - 48), + day => (_d1@1 - 48) * 10 + (_d2@1 - 48), + calendar => _calendar@1, + '__struct__' => 'Elixir.Date'}}; + __@1 -> + case __@1 of + _ -> + {error,invalid_format}; + __@2 -> + error({with_clause,__@2}) + end + end. diff --git a/lib/erl_interface/src/legacy/erl_marshal.c b/lib/erl_interface/src/legacy/erl_marshal.c index c18067b9bc..932bba43bf 100644 --- a/lib/erl_interface/src/legacy/erl_marshal.c +++ b/lib/erl_interface/src/legacy/erl_marshal.c @@ -1803,7 +1803,7 @@ static int cmp_exe2(unsigned char **e1, unsigned char **e2) k = 0; while (1) { if (k++ == min){ - if (i == j) return 0; + if (i == j) return compare_top_ext(e1 , e2); if (i < j) return -1; return 1; } diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c index 1e986feacf..04e8ca322e 100644 --- a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c +++ b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c @@ -88,6 +88,11 @@ TESTCASE(compare_list) { // erlang:term_to_binary([0, 1000]) unsigned char term4[] = {131,108,0,0,0,2,97,0,98,0,0,3,232,106}; + // erlang:term_to_binary([a|b]) + unsigned char term5a[] = {131,108,0,0,0,1,100,0,1,97,100,0,1,98}; + // erlang:term_to_binary([a|c]) + unsigned char term5b[] = {131,108,0,0,0,1,100,0,1,97,100,0,1,99}; + erl_init(NULL, 0); start_a = term1; start_b = term2; @@ -103,6 +108,13 @@ TESTCASE(compare_list) { test_compare_ext("lists1", start_a, end_a, start_b, end_b, -1); + start_a = term5a; + start_b = term5b; + end_a = term5a + sizeof(term5a); + end_b = term5b + sizeof(term5b); + + test_compare_ext("lists5", start_a, end_a, start_b, end_b, -1); + report(1); } diff --git a/lib/stdlib/src/ms_transform.erl b/lib/stdlib/src/ms_transform.erl index d117481d2e..3845e35e9b 100644 --- a/lib/stdlib/src/ms_transform.erl +++ b/lib/stdlib/src/ms_transform.erl @@ -224,10 +224,12 @@ transform_from_shell(Dialect, Clauses, BoundEnvironment) -> %% Called when translating during compiling %% --spec parse_transform(Forms, Options) -> Forms2 when +-spec parse_transform(Forms, Options) -> Forms2 | Errors | Warnings when Forms :: [erl_parse:abstract_form() | erl_parse:form_info()], Forms2 :: [erl_parse:abstract_form() | erl_parse:form_info()], - Options :: term(). + Options :: term(), + Errors :: {error, ErrInfo :: [tuple()], WarnInfo :: []}, + Warnings :: {warning, Forms2, WarnInfo :: [tuple()]}. parse_transform(Forms, _Options) -> SaveFilename = setup_filename(), |