diff options
author | Hans Bolinder <[email protected]> | 2015-09-07 08:19:36 +0200 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2015-09-07 08:19:36 +0200 |
commit | dc12459b49c8332a574fb9ffe5272587c8ed8d4f (patch) | |
tree | 1c491f73bf9f264e5d150ec3a583a3856e05e49e /lib/hipe | |
parent | 7ca6ef08b9cc7f29868afb22db9a67dc1068f12e (diff) | |
parent | 2785d9952f45fff1956243c25042b75b299af3de (diff) | |
download | otp-dc12459b49c8332a574fb9ffe5272587c8ed8d4f.tar.gz otp-dc12459b49c8332a574fb9ffe5272587c8ed8d4f.tar.bz2 otp-dc12459b49c8332a574fb9ffe5272587c8ed8d4f.zip |
Merge branch 'maint'
* maint:
dialyzer: Fix erlang:abs/1
Diffstat (limited to 'lib/hipe')
-rw-r--r-- | lib/hipe/cerl/erl_bif_types.erl | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl index dc149c0d8c..b1f1689d9c 100644 --- a/lib/hipe/cerl/erl_bif_types.erl +++ b/lib/hipe/cerl/erl_bif_types.erl @@ -514,14 +514,15 @@ type(erlang, 'bsl', 2, Xs, Opaques) -> type(erlang, 'bnot', 1, Xs, Opaques) -> strict(erlang, 'bnot', 1, Xs, fun ([X1]) -> - case arith('bnot', X1, Opaques) of + case arith_bnot(X1, Opaques) of error -> t_integer(); {ok, T} -> T end end, Opaques); %% Guard bif, needs to be here. type(erlang, abs, 1, Xs, Opaques) -> - strict(erlang, abs, 1, Xs, fun ([X]) -> X end, Opaques); + strict(erlang, abs, 1, Xs, + fun ([X1]) -> arith_abs(X1, Opaques) end, Opaques); %% This returns (-X)-1, so it often gives a negative result. %% strict(erlang, 'bnot', 1, Xs, fun (_) -> t_integer() end, Opaques); type(erlang, append, 2, Xs, _Opaques) -> type(erlang, '++', 2, Xs); % alias @@ -1926,7 +1927,7 @@ negwidth(X, N) -> false -> negwidth(X, N+1) end. -arith('bnot', X1, Opaques) -> +arith_bnot(X1, Opaques) -> case t_is_integer(X1, Opaques) of false -> error; true -> @@ -1936,6 +1937,28 @@ arith('bnot', X1, Opaques) -> infinity_add(infinity_inv(Min1), -1))} end. +arith_abs(X1, Opaques) -> + case t_is_integer(X1, Opaques) of + false -> + case t_is_float(X1, Opaques) of + true -> t_float(); + false -> t_number() + end; + true -> + Min1 = number_min(X1, Opaques), + Max1 = number_max(X1, Opaques), + {NewMin, NewMax} = + case infinity_geq(Min1, 0) of + true -> {Min1, Max1}; + false -> + case infinity_geq(Max1, 0) of + true -> {0, infinity_inv(Min1)}; + false -> {infinity_inv(Max1), infinity_inv(Min1)} + end + end, + t_from_range(NewMin, NewMax) + end. + arith_mult(Min1, Max1, Min2, Max2) -> Tmp_list = [infinity_mult(Min1, Min2), infinity_mult(Min1, Max2), infinity_mult(Max1, Min2), infinity_mult(Max1, Max2)], |