diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compiler/doc/src/notes.xml | 44 | ||||
-rw-r--r-- | lib/compiler/src/beam_ssa_pre_codegen.erl | 68 | ||||
-rw-r--r-- | lib/compiler/test/beam_ssa_SUITE.erl | 41 | ||||
-rw-r--r-- | lib/compiler/vsn.mk | 2 | ||||
-rw-r--r-- | lib/dialyzer/doc/src/notes.xml | 20 | ||||
-rw-r--r-- | lib/dialyzer/vsn.mk | 2 | ||||
-rw-r--r-- | lib/hipe/doc/src/notes.xml | 20 | ||||
-rw-r--r-- | lib/hipe/vsn.mk | 2 | ||||
-rw-r--r-- | lib/ssl/doc/src/notes.xml | 32 | ||||
-rw-r--r-- | lib/ssl/src/ssl_connection.erl | 57 | ||||
-rw-r--r-- | lib/ssl/src/tls_record.erl | 23 | ||||
-rw-r--r-- | lib/ssl/test/ssl_dist_SUITE.erl | 4 | ||||
-rw-r--r-- | lib/ssl/vsn.mk | 2 |
13 files changed, 293 insertions, 24 deletions
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml index f0d869381b..f11444137d 100644 --- a/lib/compiler/doc/src/notes.xml +++ b/lib/compiler/doc/src/notes.xml @@ -32,6 +32,50 @@ <p>This document describes the changes made to the Compiler application.</p> +<section><title>Compiler 7.4.4</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed a compiler crash introduced in <c>22.0.6</c> + (OTP-15952).</p> + <p> + Own Id: OTP-15953 Aux Id: ERL-999 </p> + </item> + </list> + </section> + +</section> + +<section><title>Compiler 7.4.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Fixed an unsafe optimization when matching + <c>tuple_size/1</c> outside of guards, which could crash + the emulator if the argument was not a tuple.</p> + <p> + Own Id: OTP-15945</p> + </item> + <item> + <p>Fixed a rare bug that could cause the wrong kind of + exception to be thrown when a BIF failed in a function + that matched bitstrings.</p> + <p> + Own Id: OTP-15946</p> + </item> + <item> + <p>Fixed a bug where receive statements inside try/catch + blocks could return incorrect results.</p> + <p> + Own Id: OTP-15952</p> + </item> + </list> + </section> + +</section> + <section><title>Compiler 7.4.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/compiler/src/beam_ssa_pre_codegen.erl b/lib/compiler/src/beam_ssa_pre_codegen.erl index 9af72afca7..7ef604d444 100644 --- a/lib/compiler/src/beam_ssa_pre_codegen.erl +++ b/lib/compiler/src/beam_ssa_pre_codegen.erl @@ -156,7 +156,9 @@ passes(Opts) -> %% Allocate registers. ?PASS(linear_scan), ?PASS(frame_size), - ?PASS(turn_yregs)], + ?PASS(turn_yregs), + + ?PASS(assert_no_critical_edges)], [P || P <- Ps, P =/= ignore]. function(#b_function{anno=Anno,args=Args,bs=Blocks0,cnt=Count0}=F0, @@ -1321,10 +1323,11 @@ fix_receives_1([{L,Blk}|Ls], Blocks0, Count0) -> LoopExit = find_loop_exit(Rm, Blocks0), Defs0 = beam_ssa:def([L], Blocks0), CommonUsed = recv_common(Defs0, LoopExit, Blocks0), - {Blocks1,Count1} = recv_fix_common(CommonUsed, LoopExit, Rm, - Blocks0, Count0), + {Blocks1,Count1} = recv_crit_edges(Rm, LoopExit, Blocks0, Count0), + {Blocks2,Count2} = recv_fix_common(CommonUsed, LoopExit, Rm, + Blocks1, Count1), Defs = ordsets:subtract(Defs0, CommonUsed), - {Blocks,Count} = fix_receive(Rm, Defs, Blocks1, Count1), + {Blocks,Count} = fix_receive(Rm, Defs, Blocks2, Count2), fix_receives_1(Ls, Blocks, Count); #b_blk{} -> fix_receives_1(Ls, Blocks0, Count0) @@ -1341,6 +1344,57 @@ recv_common(Defs, Exit, Blocks) -> Def = ordsets:subtract(Defs, ExitDefs), ordsets:intersection(Def, ExitUsed). +%% recv_crit_edges([RemoveMessageLabel], LoopExit, +%% Blocks0, Count0) -> {Blocks,Count}. +%% +%% Adds dummy blocks on all conditional jumps to the exit block so that +%% recv_fix_common/5 can insert phi nodes without having to worry about +%% critical edges. + +recv_crit_edges(_Rms, none, Blocks0, Count0) -> + {Blocks0, Count0}; +recv_crit_edges(Rms, Exit, Blocks0, Count0) -> + Ls = beam_ssa:rpo(Rms, Blocks0), + rce_insert_edges(Ls, Exit, Count0, Blocks0). + +rce_insert_edges([L | Ls], Exit, Count0, Blocks0) -> + Successors = beam_ssa:successors(map_get(L, Blocks0)), + case member(Exit, Successors) of + true when Successors =/= [Exit] -> + {Blocks, Count} = rce_insert_edge(L, Exit, Count0, Blocks0), + rce_insert_edges(Ls, Exit, Count, Blocks); + _ -> + rce_insert_edges(Ls, Exit, Count0, Blocks0) + end; +rce_insert_edges([], _Exit, Count, Blocks) -> + {Blocks, Count}. + +rce_insert_edge(L, Exit, Count, Blocks0) -> + #b_blk{last=Last0} = FromBlk0 = map_get(L, Blocks0), + + ToExit = #b_br{bool=#b_literal{val=true},succ=Exit,fail=Exit}, + + FromBlk = FromBlk0#b_blk{last=rce_reroute_terminator(Last0, Exit, Count)}, + EdgeBlk = #b_blk{anno=#{},is=[],last=ToExit}, + + Blocks = Blocks0#{ Count => EdgeBlk, L => FromBlk }, + {Blocks, Count + 1}. + +rce_reroute_terminator(#b_br{succ=Exit}=Last, Exit, New) -> + rce_reroute_terminator(Last#b_br{succ=New}, Exit, New); +rce_reroute_terminator(#b_br{fail=Exit}=Last, Exit, New) -> + rce_reroute_terminator(Last#b_br{fail=New}, Exit, New); +rce_reroute_terminator(#b_br{}=Last, _Exit, _New) -> + Last; +rce_reroute_terminator(#b_switch{fail=Exit}=Last, Exit, New) -> + rce_reroute_terminator(Last#b_switch{fail=New}, Exit, New); +rce_reroute_terminator(#b_switch{list=List0}=Last, Exit, New) -> + List = [if + Lbl =:= Exit -> {Arg, New}; + Lbl =/= Exit -> {Arg, Lbl} + end || {Arg, Lbl} <- List0], + Last#b_switch{list=List}. + %% recv_fix_common([CommonVar], LoopExit, [RemoveMessageLabel], %% Blocks0, Count0) -> {Blocks,Count}. %% Handle variables alwys defined in a receive and used @@ -1418,10 +1472,14 @@ find_loop_exit([L1,L2|_Ls], Blocks) -> find_loop_exit_1(Path1, cerl_sets:from_list(Path2)); find_loop_exit(_, _) -> none. +find_loop_exit_1([?BADARG_BLOCK | T], OtherPath) -> + %% ?BADARG_BLOCK is a marker and not an actual block, so we can't consider + %% it to be a common block even if both paths cross it. + find_loop_exit_1(T, OtherPath); find_loop_exit_1([H|T], OtherPath) -> case cerl_sets:is_element(H, OtherPath) of true -> H; - false -> find_loop_exit_1(T, OtherPath) + false -> find_loop_exit_1(T, OtherPath) end; find_loop_exit_1([], _) -> none. diff --git a/lib/compiler/test/beam_ssa_SUITE.erl b/lib/compiler/test/beam_ssa_SUITE.erl index a741ebbdf9..dd1b7ddcd3 100644 --- a/lib/compiler/test/beam_ssa_SUITE.erl +++ b/lib/compiler/test/beam_ssa_SUITE.erl @@ -190,6 +190,15 @@ recv(_Config) -> self() ! {[self(),r1],{2,99,<<"data">>}}, {Parent,r1,<<1:32,2:8,99:8,"data">>} = tricky_recv_4(), + %% Test tricky_recv_5/0. + self() ! 1, + a = tricky_recv_5(), + self() ! 2, + b = tricky_recv_5(), + + %% tricky_recv_6/0 is a compile-time error. + tricky_recv_6(), + ok. sync_wait_mon({Pid, Ref}, Timeout) -> @@ -295,6 +304,38 @@ tricky_recv_4() -> end, id({Pid,R,Request}). +%% beam_ssa_pre_codegen would accidentally create phi nodes on critical edges +%% when fixing up receives; the call to id/2 can either succeed or land in the +%% catch block, and we added a phi node to its immediate successor. +tricky_recv_5() -> + try + receive + X=1 -> + id(42), + a; + X=2 -> + b + end, + case X of + 1 -> a; + 2 -> b + end + catch + _:_ -> c + end. + +%% When fixing tricky_recv_5, we introduced a compiler crash when the common +%% exit block was ?BADARG_BLOCK and floats were in the picture. +tricky_recv_6() -> + RefA = make_ref(), + RefB = make_ref(), + receive + {RefA, Number} -> Number + 1.0; + {RefB, Number} -> Number + 2.0 + after 0 -> + ok + end. + maps(_Config) -> {'EXIT',{{badmatch,#{}},_}} = (catch maps_1(any)), ok. diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk index 508bbc902c..7192ddca15 100644 --- a/lib/compiler/vsn.mk +++ b/lib/compiler/vsn.mk @@ -1 +1 @@ -COMPILER_VSN = 7.4.2 +COMPILER_VSN = 7.4.4 diff --git a/lib/dialyzer/doc/src/notes.xml b/lib/dialyzer/doc/src/notes.xml index b72453aac7..dad9fd18c7 100644 --- a/lib/dialyzer/doc/src/notes.xml +++ b/lib/dialyzer/doc/src/notes.xml @@ -32,6 +32,26 @@ <p>This document describes the changes made to the Dialyzer application.</p> +<section><title>Dialyzer 4.0.3</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>The HiPE compiler would badly miscompile certain + try/catch expressions, so it will now refuse to compile + modules containing try or catch.</p> <p>As a consequence + of this, <c>dialyzer</c> will no longer compile key + modules to native code.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-15949</p> + </item> + </list> + </section> + +</section> + <section><title>Dialyzer 4.0.2</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/dialyzer/vsn.mk b/lib/dialyzer/vsn.mk index 7a44daf683..a77c74c717 100644 --- a/lib/dialyzer/vsn.mk +++ b/lib/dialyzer/vsn.mk @@ -1 +1 @@ -DIALYZER_VSN = 4.0.2 +DIALYZER_VSN = 4.0.3 diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml index a2e0766bb7..3fad2ac53a 100644 --- a/lib/hipe/doc/src/notes.xml +++ b/lib/hipe/doc/src/notes.xml @@ -31,6 +31,26 @@ </header> <p>This document describes the changes made to HiPE.</p> +<section><title>Hipe 3.19.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>The HiPE compiler would badly miscompile certain + try/catch expressions, so it will now refuse to compile + modules containing try or catch.</p> <p>As a consequence + of this, <c>dialyzer</c> will no longer compile key + modules to native code.</p> + <p> + *** POTENTIAL INCOMPATIBILITY ***</p> + <p> + Own Id: OTP-15949</p> + </item> + </list> + </section> + +</section> + <section><title>Hipe 3.19</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk index a91d92ca14..3a22e07f57 100644 --- a/lib/hipe/vsn.mk +++ b/lib/hipe/vsn.mk @@ -1 +1 @@ -HIPE_VSN = 3.19 +HIPE_VSN = 3.19.1 diff --git a/lib/ssl/doc/src/notes.xml b/lib/ssl/doc/src/notes.xml index c7a0942932..335896c60a 100644 --- a/lib/ssl/doc/src/notes.xml +++ b/lib/ssl/doc/src/notes.xml @@ -27,6 +27,22 @@ </header> <p>This document describes the changes made to the SSL application.</p> +<section><title>SSL 9.3.5</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p> + Enhance error handling for erroneous alerts from the + peer.</p> + <p> + Own Id: OTP-15943</p> + </item> + </list> + </section> + +</section> + <section><title>SSL 9.3.4</title> <section><title>Fixed Bugs and Malfunctions</title> @@ -210,6 +226,22 @@ </section> +<section><title>SSL 9.2.3.5</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Handling of zero size fragments in TLS could cause an + infinite loop. This has now been corrected.</p> + <p> + Own Id: OTP-15328 Aux Id: ERIERL-379 </p> + </item> + </list> + </section> + +</section> + <section><title>SSL 9.2.3.4</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl index cc4d60389e..de12de646c 100644 --- a/lib/ssl/src/ssl_connection.erl +++ b/lib/ssl/src/ssl_connection.erl @@ -614,7 +614,8 @@ read_application_dist_data(DHandle, Front0, BufferSize, Rear0, Bin0) -> <<SizeA:32, DataA:SizeA/binary, SizeB:32, DataB:SizeB/binary, SizeC:32, DataC:SizeC/binary, - SizeD:32, DataD:SizeD/binary, Rest/binary>> -> + SizeD:32, DataD:SizeD/binary, Rest/binary>> + when 0 < SizeA, 0 < SizeB, 0 < SizeC, 0 < SizeD -> %% We have 4 complete packets in the first binary erlang:dist_ctrl_put_data(DHandle, DataA), erlang:dist_ctrl_put_data(DHandle, DataB), @@ -624,7 +625,8 @@ read_application_dist_data(DHandle, Front0, BufferSize, Rear0, Bin0) -> DHandle, Front0, BufferSize - (4*4+SizeA+SizeB+SizeC+SizeD), Rear0, Rest); <<SizeA:32, DataA:SizeA/binary, SizeB:32, DataB:SizeB/binary, - SizeC:32, DataC:SizeC/binary, Rest/binary>> -> + SizeC:32, DataC:SizeC/binary, Rest/binary>> + when 0 < SizeA, 0 < SizeB, 0 < SizeC -> %% We have 3 complete packets in the first binary erlang:dist_ctrl_put_data(DHandle, DataA), erlang:dist_ctrl_put_data(DHandle, DataB), @@ -632,7 +634,8 @@ read_application_dist_data(DHandle, Front0, BufferSize, Rear0, Bin0) -> read_application_dist_data( DHandle, Front0, BufferSize - (3*4+SizeA+SizeB+SizeC), Rear0, Rest); <<SizeA:32, DataA:SizeA/binary, - SizeB:32, DataB:SizeB/binary, Rest/binary>> -> + SizeB:32, DataB:SizeB/binary, Rest/binary>> + when 0 < SizeA, 0 < SizeB -> %% We have 2 complete packets in the first binary erlang:dist_ctrl_put_data(DHandle, DataA), erlang:dist_ctrl_put_data(DHandle, DataB), @@ -643,13 +646,13 @@ read_application_dist_data(DHandle, Front0, BufferSize, Rear0, Bin0) -> %% Basic one packet code path <<Size:32, Data:Size/binary, Rest/binary>> -> %% We have a complete packet in the first binary - erlang:dist_ctrl_put_data(DHandle, Data), + 0 < Size andalso erlang:dist_ctrl_put_data(DHandle, Data), read_application_dist_data(DHandle, Front0, BufferSize - (4+Size), Rear0, Rest); <<Size:32, FirstData/binary>> when 4+Size =< BufferSize -> %% We have a complete packet in the buffer %% - fetch the missing content from the buffer front {Data,Front,Rear} = iovec_from_front(Size - byte_size(FirstData), Front0, Rear0, [FirstData]), - erlang:dist_ctrl_put_data(DHandle, Data), + 0 < Size andalso erlang:dist_ctrl_put_data(DHandle, Data), read_application_dist_data(DHandle, Front, BufferSize - (4+Size), Rear); <<Bin/binary>> -> %% In OTP-21 the match context reuse optimization fails if we use Bin0 in recursion, so here we @@ -665,23 +668,61 @@ read_application_dist_data(DHandle, Front0, BufferSize, Rear0, Bin0) -> %% contains enough data to maybe form a packet %% - fetch a tiny binary from the buffer front to complete the length field {LengthField,Front,Rear} = - iovec_from_front(4 - byte_size(IncompleteLengthField), Front0, Rear0, [IncompleteLengthField]), + case IncompleteLengthField of + <<>> -> + iovec_from_front(4, Front0, Rear0, []); + _ -> + iovec_from_front( + 4 - byte_size(IncompleteLengthField), Front0, Rear0, [IncompleteLengthField]) + end, LengthBin = iolist_to_binary(LengthField), read_application_dist_data(DHandle, Front, BufferSize, Rear, LengthBin); <<IncompleteLengthField/binary>> -> %% We do not have enough data in the buffer to even form a length field - await more data - {[IncompleteLengthField|Front0],BufferSize,Rear0} + case IncompleteLengthField of + <<>> -> + {Front0,BufferSize,Rear0}; + _ -> + {[IncompleteLengthField|Front0],BufferSize,Rear0} + end end end. +iovec_from_front(0, Front, Rear, Acc) -> + {lists:reverse(Acc),Front,Rear}; iovec_from_front(Size, [], Rear, Acc) -> - iovec_from_front(Size, lists:reverse(Rear), [], Acc); + case Rear of + %% Avoid lists:reverse/1 for simple cases. + %% Case clause for [] to avoid infinite loop. + [_] -> + iovec_from_front(Size, Rear, [], Acc); + [Bin2,Bin1] -> + iovec_from_front(Size, [Bin1,Bin2], [], Acc); + [Bin3,Bin2,Bin1] -> + iovec_from_front(Size, [Bin1,Bin2,Bin3], [], Acc); + [_,_,_|_] = Rear -> + iovec_from_front(Size, lists:reverse(Rear), [], Acc) + end; +iovec_from_front(Size, [Bin|Front], Rear, []) -> + case Bin of + <<Last:Size/binary>> -> % Just enough + {[Last],Front,Rear}; + <<Last:Size/binary, Rest/binary>> -> % More than enough, split here + {[Last],[Rest|Front],Rear}; + <<>> -> % Not enough, skip empty binaries + iovec_from_front(Size, Front, Rear, []); + <<_/binary>> -> % Not enough + BinSize = byte_size(Bin), + iovec_from_front(Size - BinSize, Front, Rear, [Bin]) + end; iovec_from_front(Size, [Bin|Front], Rear, Acc) -> case Bin of <<Last:Size/binary>> -> % Just enough {lists:reverse(Acc, [Last]),Front,Rear}; <<Last:Size/binary, Rest/binary>> -> % More than enough, split here {lists:reverse(Acc, [Last]),[Rest|Front],Rear}; + <<>> -> % Not enough, skip empty binaries + iovec_from_front(Size, Front, Rear, Acc); <<_/binary>> -> % Not enough BinSize = byte_size(Bin), iovec_from_front(Size - BinSize, Front, Rear, [Bin|Acc]) diff --git a/lib/ssl/src/tls_record.erl b/lib/ssl/src/tls_record.erl index a5c550a429..2aeab98929 100644 --- a/lib/ssl/src/tls_record.erl +++ b/lib/ssl/src/tls_record.erl @@ -514,16 +514,27 @@ validate_tls_record_length(Versions, {_,Size0,_} = Q0, SslOpts, Acc, Type, Versi end. -binary_from_front(SplitSize, {Front,Size,Rear}) -> +binary_from_front(0, Q) -> + {<<>>, Q}; +binary_from_front(SplitSize, {Front,Size,Rear}) when SplitSize =< Size -> binary_from_front(SplitSize, Front, Size, Rear, []). %% -binary_from_front(SplitSize, [], Size, [_] = Rear, Acc) -> - %% Optimize a simple case - binary_from_front(SplitSize, Rear, Size, [], Acc); +%% SplitSize > 0 and there is at least SplitSize bytes buffered in Front and Rear binary_from_front(SplitSize, [], Size, Rear, Acc) -> - binary_from_front(SplitSize, lists:reverse(Rear), Size, [], Acc); + case Rear of + %% Avoid lists:reverse/1 for simple cases. + %% Case clause for [] to avoid infinite loop. + [_] -> + binary_from_front(SplitSize, Rear, Size, [], Acc); + [Bin2,Bin1] -> + binary_from_front(SplitSize, [Bin1,Bin2], Size, [], Acc); + [Bin3,Bin2,Bin1] -> + binary_from_front(SplitSize, [Bin1,Bin2,Bin3], Size, [], Acc); + [_,_,_|_] -> + binary_from_front(SplitSize, lists:reverse(Rear), Size, [], Acc) + end; binary_from_front(SplitSize, [Bin|Front], Size, Rear, []) -> - %% Optimize a frequent case + %% Optimize the frequent case when the accumulator is empty BinSize = byte_size(Bin), if SplitSize < BinSize -> diff --git a/lib/ssl/test/ssl_dist_SUITE.erl b/lib/ssl/test/ssl_dist_SUITE.erl index 003e1fc448..7cfb2ac0c5 100644 --- a/lib/ssl/test/ssl_dist_SUITE.erl +++ b/lib/ssl/test/ssl_dist_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2018. All Rights Reserved. +%% Copyright Ericsson AB 2007-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -311,9 +311,11 @@ listen_port_options(Config) when is_list(Config) -> catch _:Reason -> stop_ssl_node(NH2), + stop_ssl_node(NH1), ct:fail(Reason) end, stop_ssl_node(NH2), + stop_ssl_node(NH1), success(Config). %%-------------------------------------------------------------------- diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk index df38aea017..c9547cae36 100644 --- a/lib/ssl/vsn.mk +++ b/lib/ssl/vsn.mk @@ -1 +1 @@ -SSL_VSN = 9.3.4 +SSL_VSN = 9.3.5 |