aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/doc/src/notes.xml17
-rw-r--r--lib/compiler/src/beam_block.erl98
-rw-r--r--lib/compiler/src/beam_dead.erl7
-rw-r--r--lib/compiler/test/Makefile4
-rw-r--r--lib/compiler/test/beam_block_SUITE.erl27
-rw-r--r--lib/compiler/test/bif_SUITE.erl45
-rw-r--r--lib/compiler/test/match_SUITE.erl13
-rw-r--r--lib/compiler/test/num_bif_SUITE.erl285
-rw-r--r--lib/compiler/vsn.mk2
9 files changed, 163 insertions, 335 deletions
diff --git a/lib/compiler/doc/src/notes.xml b/lib/compiler/doc/src/notes.xml
index e25cdc580c..92b3d809fc 100644
--- a/lib/compiler/doc/src/notes.xml
+++ b/lib/compiler/doc/src/notes.xml
@@ -32,6 +32,23 @@
<p>This document describes the changes made to the Compiler
application.</p>
+<section><title>Compiler 7.0.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ A literal binary matching regression was introduced in
+ 19.0 where a match could fail to resolve to the right
+ clause. This has now been fixed.</p>
+ <p>
+ Own Id: OTP-13738</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Compiler 7.0</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl
index 85d332c56e..ec41925beb 100644
--- a/lib/compiler/src/beam_block.erl
+++ b/lib/compiler/src/beam_block.erl
@@ -159,14 +159,43 @@ find_fixpoint(OptFun, Is0) ->
end.
%% move_allocates(Is0) -> Is
-%% Move allocate instructions upwards in the instruction stream, in the
-%% hope of getting more possibilities for optimizing away moves later.
+%% Move allocate instructions upwards in the instruction stream
+%% (within the same block), in the hope of getting more possibilities
+%% for optimizing away moves later.
%%
-%% NOTE: Moving allocation instructions is only safe because it is done
-%% immediately after code generation so that we KNOW that if {x,X} is
-%% initialized, all x registers with lower numbers are also initialized.
-%% That assumption may not be true after other optimizations, such as
-%% the beam_utils:live_opt/1 optimization.
+%% For example, we can transform the following instructions:
+%%
+%% get_tuple_element x(1) Element => x(2)
+%% allocate_zero StackSize 3 %% x(0), x(1), x(2) are live
+%%
+%% to the following instructions:
+%%
+%% allocate_zero StackSize 2 %% x(0) and x(1) are live
+%% get_tuple_element x(1) Element => x(2)
+%%
+%% NOTE: Since the beam_reorder pass has been run, it is no longer
+%% safe to assume that if x(N) is initialized, then all lower-numbered
+%% x registers are also initialized.
+%%
+%% For example, in general it is not safe to transform the following
+%% instructions:
+%%
+%% get_tuple_element x(0) Element => x(1)
+%% allocate_zero StackSize 3 %x(0), x(1), x(2) are live
+%%
+%% to the following instructions:
+%%
+%% allocate_zero StackSize 3
+%% get_tuple_element x(0) Element => x(1)
+%%
+%% The transformation is safe if and only if x(1) has been
+%% initialized previously. Unfortunately, beam_reorder may have moved
+%% a get_tuple_element instruction so that x(1) is not always
+%% initialized when this code is reached. To find whether or not x(1)
+%% is initialized, we would need to analyze all code preceding these
+%% two instructions (across branches). Since we currently don't have
+%% any practical mechanism for doing that, we will have to
+%% conservatively assume that the transformation is unsafe.
move_allocates([{block,Bl0}|Is]) ->
Bl = move_allocates_1(reverse(Bl0), []),
@@ -175,27 +204,19 @@ move_allocates([I|Is]) ->
[I|move_allocates(Is)];
move_allocates([]) -> [].
-move_allocates_1([{set,[],[],{alloc,_,_}=Alloc}|Is0], Acc0) ->
- {Is,Acc} = move_allocates_2(Alloc, Is0, Acc0),
- move_allocates_1(Is, Acc);
+move_allocates_1([I|Is], [{set,[],[],{alloc,Live0,Info}}|Acc]=Acc0) ->
+ case {alloc_may_pass(I),alloc_live_regs(I, Live0)} of
+ {false,_} ->
+ move_allocates_1(Is, [I|Acc0]);
+ {true,not_possible} ->
+ move_allocates_1(Is, [I|Acc0]);
+ {true,Live} when is_integer(Live) ->
+ A = {set,[],[],{alloc,Live,Info}},
+ move_allocates_1(Is, [A,I|Acc])
+ end;
move_allocates_1([I|Is], Acc) ->
move_allocates_1(Is, [I|Acc]);
-move_allocates_1([], Is) -> Is.
-
-move_allocates_2({alloc,Live,Info}, [{set,[],[],{alloc,Live0,Info0}}|Is], Acc) ->
- Live = Live0, % Assertion.
- Alloc = {alloc,Live,combine_alloc(Info0, Info)},
- move_allocates_2(Alloc, Is, Acc);
-move_allocates_2({alloc,Live,Info}=Alloc0, [I|Is]=Is0, Acc) ->
- case alloc_may_pass(I) of
- false ->
- {Is0,[{set,[],[],Alloc0}|Acc]};
- true ->
- Alloc = {alloc,alloc_live_regs(I, Live),Info},
- move_allocates_2(Alloc, Is, [I|Acc])
- end;
-move_allocates_2(Alloc, [], Acc) ->
- {[],[{set,[],[],Alloc}|Acc]}.
+move_allocates_1([], Acc) -> Acc.
alloc_may_pass({set,_,_,{alloc,_,_}}) -> false;
alloc_may_pass({set,_,_,{set_tuple_element,_}}) -> false;
@@ -204,9 +225,6 @@ alloc_may_pass({set,_,_,put_list}) -> false;
alloc_may_pass({set,_,_,put}) -> false;
alloc_may_pass({set,_,_,_}) -> true.
-combine_alloc({_,Ns,Nh1,Init}, {_,nostack,Nh2,[]}) ->
- {zero,Ns,beam_utils:combine_heap_needs(Nh1, Nh2),Init}.
-
%% opt([Instruction]) -> [Instruction]
%% Optimize the instruction stream inside a basic block.
@@ -393,10 +411,19 @@ eliminate_use_of_from_reg([I]=Is, From, _To, Acc) ->
%% opt_alloc(Instructions) -> Instructions'
%% Optimises all allocate instructions.
+opt_alloc([{set,[],[],{alloc,Live0,Info0}},
+ {set,[],[],{alloc,Live,Info}}|Is]) ->
+ Live = Live0, %Assertion.
+ Alloc = combine_alloc(Info0, Info),
+ I = {set,[],[],{alloc,Live,Alloc}},
+ opt_alloc([I|Is]);
opt_alloc([{set,[],[],{alloc,R,{_,Ns,Nh,[]}}}|Is]) ->
[{set,[],[],opt_alloc(Is, Ns, Nh, R)}|Is];
opt_alloc([I|Is]) -> [I|opt_alloc(Is)];
opt_alloc([]) -> [].
+
+combine_alloc({_,Ns,Nh1,Init}, {_,nostack,Nh2,[]}) ->
+ {zero,Ns,beam_utils:combine_heap_needs(Nh1, Nh2),Init}.
%% opt_alloc(Instructions, FrameSize, HeapNeed, LivingRegs) -> [Instr]
%% Generates the optimal sequence of instructions for
@@ -445,13 +472,14 @@ count_ones(Bits, Acc) ->
alloc_live_regs({set,Ds,Ss,_}, Regs0) ->
Rset = x_live(Ss, x_dead(Ds, (1 bsl Regs0)-1)),
- live_regs(Rset).
+ live_regs(0, Rset).
-live_regs(Regs) ->
- live_regs_1(0, Regs).
-
-live_regs_1(N, 0) -> N;
-live_regs_1(N, Regs) -> live_regs_1(N+1, Regs bsr 1).
+live_regs(N, 0) ->
+ N;
+live_regs(N, Regs) when Regs band 1 =:= 1 ->
+ live_regs(N+1, Regs bsr 1);
+live_regs(_, _) ->
+ not_possible.
x_dead([{x,N}|Rs], Regs) -> x_dead(Rs, Regs band (bnot (1 bsl N)));
x_dead([_|Rs], Regs) -> x_dead(Rs, Regs);
diff --git a/lib/compiler/src/beam_dead.erl b/lib/compiler/src/beam_dead.erl
index b01f58f683..6f6d742293 100644
--- a/lib/compiler/src/beam_dead.erl
+++ b/lib/compiler/src/beam_dead.erl
@@ -272,17 +272,14 @@ backward([{jump,{f,To}}=J|[{bif,Op,_,Ops,Reg}|Is]=Is0], D, Acc) ->
catch
throw:not_possible -> backward(Is0, D, [J|Acc])
end;
-backward([{test,bs_start_match2,F,Live,[R,_]=Args,Ctxt}|Is], D,
+backward([{test,bs_start_match2,F,_,[R,_],Ctxt}=I|Is], D,
[{test,bs_match_string,F,[Ctxt,Bs]},
{test,bs_test_tail2,F,[Ctxt,0]}|Acc0]=Acc) ->
- {f,To0} = F,
- To = shortcut_bs_start_match(To0, R, D),
case beam_utils:is_killed(Ctxt, Acc0, D) of
true ->
- Eq = {test,is_eq_exact,{f,To},[R,{literal,Bs}]},
+ Eq = {test,is_eq_exact,F,[R,{literal,Bs}]},
backward(Is, D, [Eq|Acc0]);
false ->
- I = {test,bs_start_match2,{f,To},Live,Args,Ctxt},
backward(Is, D, [I|Acc])
end;
backward([{test,bs_start_match2,{f,To0},Live,[Src|_]=Info,Dst}|Is], D, Acc) ->
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index f0185acbc7..365f4c295e 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -36,7 +36,6 @@ MODULES= \
map_SUITE \
match_SUITE \
misc_SUITE \
- num_bif_SUITE \
receive_SUITE \
record_SUITE \
regressions_SUITE \
@@ -67,7 +66,6 @@ NO_OPT= \
map \
match \
misc \
- num_bif \
receive \
record \
trycatch
@@ -78,6 +76,7 @@ INLINE= \
beam_block \
beam_bool \
beam_utils \
+ bif \
bs_bincomp \
bs_bit_binaries \
bs_construct \
@@ -91,7 +90,6 @@ INLINE= \
map \
match \
misc \
- num_bif \
receive \
record
diff --git a/lib/compiler/test/beam_block_SUITE.erl b/lib/compiler/test/beam_block_SUITE.erl
index 4bcb252833..9fcb6e497d 100644
--- a/lib/compiler/test/beam_block_SUITE.erl
+++ b/lib/compiler/test/beam_block_SUITE.erl
@@ -21,7 +21,8 @@
-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
init_per_group/2,end_per_group/2,
- get_map_elements/1,otp_7345/1,move_opt_across_gc_bif/1]).
+ get_map_elements/1,otp_7345/1,move_opt_across_gc_bif/1,
+ erl_202/1]).
%% The only test for the following functions is that
%% the code compiles and is accepted by beam_validator.
@@ -37,7 +38,8 @@ groups() ->
[{p,[parallel],
[get_map_elements,
otp_7345,
- move_opt_across_gc_bif
+ move_opt_across_gc_bif,
+ erl_202
]}].
init_per_suite(Config) ->
@@ -135,6 +137,27 @@ positive(speaking) ->
paris([], P) -> P + 1.
+
+%% See https://bugs.erlang.org/browse/ERL-202.
+%% Test that move_allocates/1 in beam_block doesn't move allocate
+%% when it would not be safe.
+
+-record(erl_202_r1, {y}).
+-record(erl_202_r2, {x}).
+
+erl_202(_Config) ->
+ Ref = make_ref(),
+ Ref = erl_202({{1,2},Ref}, 42),
+
+ {Ref} = erl_202({7,8}, #erl_202_r1{y=#erl_202_r2{x=Ref}}),
+
+ ok.
+
+erl_202({{_, _},X}, _) ->
+ X;
+erl_202({_, _}, #erl_202_r1{y=R2}) ->
+ {R2#erl_202_r2.x}.
+
%%%
%%% The only test of the following code is that it compiles.
%%%
diff --git a/lib/compiler/test/bif_SUITE.erl b/lib/compiler/test/bif_SUITE.erl
index 51bc71da81..6d7231b426 100644
--- a/lib/compiler/test/bif_SUITE.erl
+++ b/lib/compiler/test/bif_SUITE.erl
@@ -19,9 +19,11 @@
%%
-module(bif_SUITE).
+-include_lib("syntax_tools/include/merl.hrl").
+
-export([all/0,suite/0,groups/0,init_per_suite/1,end_per_suite/1,
init_per_group/2,end_per_group/2,
- beam_validator/1]).
+ beam_validator/1,trunc_and_friends/1]).
suite() ->
[{ct_hooks,[ts_install_cth]}].
@@ -32,7 +34,8 @@ all() ->
groups() ->
[{p,[parallel],
- [beam_validator
+ [beam_validator,
+ trunc_and_friends
]}].
init_per_suite(Config) ->
@@ -63,3 +66,41 @@ food(Curriculum) ->
catch _ ->
0
end, Curriculum].
+
+%% Test trunc/1, round/1.
+trunc_and_friends(_Config) ->
+ Bifs = [trunc,round],
+ Fs = trunc_and_friends_1(Bifs),
+ Mod = ?FUNCTION_NAME,
+ Calls = [begin
+ Atom = erl_syntax:function_name(N),
+ ?Q("'@Atom'()")
+ end || N <- Fs],
+ Tree = ?Q(["-module('@Mod@').",
+ "-export([test/0]).",
+ "test() -> _@Calls, ok.",
+ "id(I) -> I."]) ++ Fs,
+ merl:print(Tree),
+ Opts = test_lib:opt_opts(?MODULE),
+ {ok,_Bin} = merl:compile_and_load(Tree, Opts),
+ Mod:test(),
+ ok.
+
+trunc_and_friends_1([F|Fs]) ->
+ Func = list_to_atom("f"++integer_to_list(length(Fs))),
+ [trunc_template(Func, F)|trunc_and_friends_1(Fs)];
+trunc_and_friends_1([]) -> [].
+
+trunc_template(Func, Bif) ->
+ Val = 42.77,
+ Res = erlang:Bif(Val),
+ FloatRes = float(Res),
+ ?Q("'@Func@'() ->
+ Var = id(_@Val@),
+ if _@Bif@(Var) =:= _@Res@ -> ok end,
+ if _@Bif@(Var) == _@FloatRes@ -> ok end,
+ if _@Bif@(Var) == _@Res@ -> ok end,
+ _@Res@ = _@Bif@(Var),
+ try begin _@Bif@(a), ok end
+ catch error:badarg -> ok end,
+ ok.").
diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl
index 31402ac717..127679ba69 100644
--- a/lib/compiler/test/match_SUITE.erl
+++ b/lib/compiler/test/match_SUITE.erl
@@ -24,7 +24,7 @@
pmatch/1,mixed/1,aliases/1,non_matching_aliases/1,
match_in_call/1,untuplify/1,shortcut_boolean/1,letify_guard/1,
selectify/1,underscore/1,match_map/1,map_vars_used/1,
- coverage/1,grab_bag/1]).
+ coverage/1,grab_bag/1,literal_binary/1]).
-include_lib("common_test/include/ct.hrl").
@@ -40,7 +40,7 @@ groups() ->
match_in_call,untuplify,
shortcut_boolean,letify_guard,selectify,
underscore,match_map,map_vars_used,coverage,
- grab_bag]}].
+ grab_bag,literal_binary]}].
init_per_suite(Config) ->
@@ -574,6 +574,15 @@ grab_bag_remove_failure([{stretch,_,Mi}=Stretch | Specs], Unit, _MaxFailure) ->
ok
end.
+%% Regression in 19.0, reported by Alexei Sholik
+literal_binary(_Config) ->
+ 3 = literal_binary_match(bar,<<"y">>),
+ ok.
+
+literal_binary_match(bar, <<"x">>) -> 1;
+literal_binary_match(_, <<"x">>) -> 2;
+literal_binary_match(_, <<"y">>) -> 3;
+literal_binary_match(_, _) -> fail.
id(I) -> I.
diff --git a/lib/compiler/test/num_bif_SUITE.erl b/lib/compiler/test/num_bif_SUITE.erl
deleted file mode 100644
index 7eac90bac3..0000000000
--- a/lib/compiler/test/num_bif_SUITE.erl
+++ /dev/null
@@ -1,285 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2004-2016. 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.
-%% You may obtain a copy of the License at
-%%
-%% http://www.apache.org/licenses/LICENSE-2.0
-%%
-%% Unless required by applicable law or agreed to in writing, software
-%% distributed under the License is distributed on an "AS IS" BASIS,
-%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-%% See the License for the specific language governing permissions and
-%% limitations under the License.
-%%
-%% %CopyrightEnd%
-%%
--module(num_bif_SUITE).
-
--include_lib("common_test/include/ct.hrl").
-
-%% Tests optimization of the BIFs:
-%% abs/1
-%% float/1
-%% float_to_list/1
-%% integer_to_list/1
-%% list_to_float/1
-%% list_to_integer/1
-%% round/1
-%% trunc/1
-
--export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
- init_per_group/2,end_per_group/2, t_abs/1, t_float/1,
- t_float_to_list/1, t_integer_to_list/1,
- t_list_to_integer/1,
- t_list_to_float_safe/1, t_list_to_float_risky/1,
- t_round/1, t_trunc/1]).
-
-suite() -> [{ct_hooks,[ts_install_cth]}].
-
-all() ->
- test_lib:recompile(?MODULE),
- [t_abs, t_float, t_float_to_list, t_integer_to_list,
- {group, t_list_to_float}, t_list_to_integer, t_round,
- t_trunc].
-
-groups() ->
- [{t_list_to_float, [],
- [t_list_to_float_safe, t_list_to_float_risky]}].
-
-init_per_suite(Config) ->
- Config.
-
-end_per_suite(_Config) ->
- ok.
-
-init_per_group(_GroupName, Config) ->
- Config.
-
-end_per_group(_GroupName, Config) ->
- Config.
-
-
-t_abs(Config) when is_list(Config) ->
- %% Floats.
- 5.5 = abs(5.5),
- 0.0 = abs(0.0),
- 100.0 = abs(-100.0),
-
- %% Integers.
- 5 = abs(5),
- 0 = abs(0),
- 100 = abs(-100),
-
- %% The largest smallnum. OTP-3190.
- X = (1 bsl 27) - 1,
- X = abs(X),
- X = abs(X-1)+1,
- X = abs(X+1)-1,
- X = abs(-X),
- X = abs(-X-1)-1,
- X = abs(-X+1)+1,
-
- %% Bignums.
- BigNum = 13984792374983749,
- BigNum = abs(BigNum),
- BigNum = abs(-BigNum),
- ok.
-
-t_float(Config) when is_list(Config) ->
- 0.0 = float(0),
- 2.5 = float(2.5),
- 0.0 = float(0.0),
- -100.55 = float(-100.55),
- 42.0 = float(42),
- -100.0 = float(-100),
-
- %% Bignums.
- 4294967305.0 = float(4294967305),
- -4294967305.0 = float(-4294967305),
-
- %% Extremly big bignums.
- Big = list_to_integer(lists:duplicate(2000, $1)),
- {'EXIT', {badarg, _}} = (catch float(Big)),
-
- %% Invalid types and lists.
- {'EXIT', {badarg, _}} = (catch list_to_integer(atom)),
- {'EXIT', {badarg, _}} = (catch list_to_integer(123)),
- {'EXIT', {badarg, _}} = (catch list_to_integer([$1, [$2]])),
- {'EXIT', {badarg, _}} = (catch list_to_integer("1.2")),
- {'EXIT', {badarg, _}} = (catch list_to_integer("a")),
- {'EXIT', {badarg, _}} = (catch list_to_integer("")),
- ok.
-
-
-%% Tests float_to_list/1.
-
-t_float_to_list(Config) when is_list(Config) ->
- test_ftl("0.0e+0", 0.0),
- test_ftl("2.5e+1", 25.0),
- test_ftl("2.5e+0", 2.5),
- test_ftl("2.5e-1", 0.25),
- test_ftl("-3.5e+17", -350.0e15),
- ok.
-
-test_ftl(Expect, Float) ->
- %% No on the next line -- we want the line number from t_float_to_list.
- Expect = remove_zeros(lists:reverse(float_to_list(Float)), []).
-
-%% Removes any non-significant zeros in a floating point number.
-%% Example: 2.500000e+01 -> 2.5e+1
-
-remove_zeros([$+, $e|Rest], [$0, X|Result]) ->
- remove_zeros([$+, $e|Rest], [X|Result]);
-remove_zeros([$-, $e|Rest], [$0, X|Result]) ->
- remove_zeros([$-, $e|Rest], [X|Result]);
-remove_zeros([$0, $.|Rest], [$e|Result]) ->
- remove_zeros(Rest, [$., $0, $e|Result]);
-remove_zeros([$0|Rest], [$e|Result]) ->
- remove_zeros(Rest, [$e|Result]);
-remove_zeros([Char|Rest], Result) ->
- remove_zeros(Rest, [Char|Result]);
-remove_zeros([], Result) ->
- Result.
-
-%% Tests integer_to_list/1.
-
-t_integer_to_list(Config) when is_list(Config) ->
- "0" = integer_to_list(0),
- "42" = integer_to_list(42),
- "-42" = integer_to_list(-42),
- "-42" = integer_to_list(-42),
- "32768" = integer_to_list(32768),
- "268435455" = integer_to_list(268435455),
- "-268435455" = integer_to_list(-268435455),
- "123456932798748738738" = integer_to_list(123456932798748738738),
- Big_List = lists:duplicate(2000, $1),
- Big = list_to_integer(Big_List),
- Big_List = integer_to_list(Big),
- ok.
-
-%% Tests list_to_float/1.
-
-
-t_list_to_float_safe(Config) when is_list(Config) ->
- 0.0 = list_to_float("0.0"),
- 0.0 = list_to_float("-0.0"),
- 0.5 = list_to_float("0.5"),
- -0.5 = list_to_float("-0.5"),
- 100.0 = list_to_float("1.0e2"),
- 127.5 = list_to_float("127.5"),
- -199.5 = list_to_float("-199.5"),
-
- {'EXIT', {badarg, _}} = (catch list_to_float("0")),
- {'EXIT', {badarg, _}} = (catch list_to_float("0..0")),
- {'EXIT', {badarg, _}} = (catch list_to_float("0e12")),
- {'EXIT', {badarg, _}} = (catch list_to_float("--0.0")),
-%% {'EXIT', {badarg, _}} = (catch list_to_float("0.0e+99999999")),
-
- ok.
-
-%% This might crash the emulator...
-%% (Known to crash the Unix version of Erlang 4.4.1)
-
-t_list_to_float_risky(Config) when is_list(Config) ->
- Many_Ones = lists:duplicate(25000, $1),
- _ = list_to_float("2."++Many_Ones),
- {'EXIT', {badarg, _}} = (catch list_to_float("2"++Many_Ones)),
- ok.
-
-%% Tests list_to_integer/1.
-
-t_list_to_integer(Config) when is_list(Config) ->
- 0 = list_to_integer("0"),
- 0 = list_to_integer("00"),
- 0 = list_to_integer("-0"),
- 1 = list_to_integer("1"),
- -1 = list_to_integer("-1"),
- 42 = list_to_integer("42"),
- -12 = list_to_integer("-12"),
- 32768 = list_to_integer("32768"),
- 268435455 = list_to_integer("268435455"),
- -268435455 = list_to_integer("-268435455"),
-
- %% Bignums.
- 123456932798748738738 = list_to_integer("123456932798748738738"),
- _ = list_to_integer(lists:duplicate(2000, $1)),
- ok.
-
-%% Tests round/1.
-
-t_round(Config) when is_list(Config) ->
- 0 = round(0.0),
- 0 = round(0.4),
- 1 = round(0.5),
- 0 = round(-0.4),
- -1 = round(-0.5),
- 255 = round(255.3),
- 256 = round(255.6),
- -1033 = round(-1033.3),
- -1034 = round(-1033.6),
-
- % OTP-3722:
- X = (1 bsl 27) - 1,
- MX = -X,
- MXm1 = -X-1,
- MXp1 = -X+1,
- F = X + 0.0,
- X = round(F),
- X = round(F+1)-1,
- X = round(F-1)+1,
- MX = round(-F),
- MXm1 = round(-F-1),
- MXp1 = round(-F+1),
-
- X = round(F+0.1),
- X = round(F+1+0.1)-1,
- X = round(F-1+0.1)+1,
- MX = round(-F+0.1),
- MXm1 = round(-F-1+0.1),
- MXp1 = round(-F+1+0.1),
-
- X = round(F-0.1),
- X = round(F+1-0.1)-1,
- X = round(F-1-0.1)+1,
- MX = round(-F-0.1),
- MXm1 = round(-F-1-0.1),
- MXp1 = round(-F+1-0.1),
-
- 0.5 = abs(round(F+0.5)-(F+0.5)),
- 0.5 = abs(round(F-0.5)-(F-0.5)),
- 0.5 = abs(round(-F-0.5)-(-F-0.5)),
- 0.5 = abs(round(-F+0.5)-(-F+0.5)),
-
- %% Bignums.
- 4294967296 = round(4294967296.1),
- 4294967297 = round(4294967296.9),
- -4294967296 = -round(4294967296.1),
- -4294967297 = -round(4294967296.9),
- ok.
-
-t_trunc(Config) when is_list(Config) ->
- 0 = trunc(0.0),
- 5 = trunc(5.3333),
- -10 = trunc(-10.978987),
- % The largest smallnum, converted to float (OTP-3722):
- X = (1 bsl 27) - 1,
- F = X + 0.0,
- io:format("X = ~p/~w/~w, F = ~p/~w/~w, trunc(F) = ~p/~w/~w~n",
- [X, X, binary_to_list(term_to_binary(X)),
- F, F, binary_to_list(term_to_binary(F)),
- trunc(F), trunc(F), binary_to_list(term_to_binary(trunc(F)))]),
- X = trunc(F),
- X = trunc(F+1)-1,
- X = trunc(F-1)+1,
- X = -trunc(-F),
- X = -trunc(-F-1)-1,
- X = -trunc(-F+1)+1,
-
- %% Bignums.
- 4294967305 = trunc(4294967305.7),
- -4294967305 = trunc(-4294967305.7),
- ok.
diff --git a/lib/compiler/vsn.mk b/lib/compiler/vsn.mk
index 23dd4bd4b1..334784657e 100644
--- a/lib/compiler/vsn.mk
+++ b/lib/compiler/vsn.mk
@@ -1 +1 @@
-COMPILER_VSN = 7.0
+COMPILER_VSN = 7.0.1