diff options
Diffstat (limited to 'lib/hipe/cerl/erl_bif_types.erl')
-rw-r--r-- | lib/hipe/cerl/erl_bif_types.erl | 110 |
1 files changed, 75 insertions, 35 deletions
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl index a460f16272..9f23b6a9b3 100644 --- a/lib/hipe/cerl/erl_bif_types.erl +++ b/lib/hipe/cerl/erl_bif_types.erl @@ -2,18 +2,19 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2013. All Rights Reserved. +%% Copyright Ericsson AB 2003-2016. All Rights Reserved. %% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. +%% 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 %% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. +%% 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% %% @@ -92,7 +93,7 @@ t_list/0, t_list/1, t_list_elements/2, - t_list_termination/1, + t_list_termination/2, t_mfa/0, t_module/0, t_nil/0, @@ -513,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 @@ -766,6 +768,18 @@ type(erlang, length, 1, Xs, Opaques) -> %% Guard bif, needs to be here. type(erlang, map_size, 1, Xs, Opaques) -> strict(erlang, map_size, 1, Xs, fun (_) -> t_non_neg_integer() end, Opaques); +type(erlang, make_fun, 3, Xs, Opaques) -> + strict(erlang, make_fun, 3, Xs, + fun ([_, _, Arity]) -> + case t_number_vals(Arity, Opaques) of + [N] -> + case is_integer(N) andalso 0 =< N andalso N =< 255 of + true -> t_fun(N, t_any()); + false -> t_none() + end; + _Other -> t_fun() + end + end, Opaques); type(erlang, make_tuple, 2, Xs, Opaques) -> strict(erlang, make_tuple, 2, Xs, fun ([Int, _]) -> @@ -1070,9 +1084,6 @@ type(hipe_bifs, find_na_or_make_stub, 2, Xs, Opaques) -> type(hipe_bifs, fun_to_address, 1, Xs, Opaques) -> strict(hipe_bifs, fun_to_address, 1, Xs, fun (_) -> t_integer() end, Opaques); -%% type(hipe_bifs, get_emu_address, 1, Xs, Opaques) -> -%% strict(hipe_bifs, get_emu_address, 1, Xs, -%% fun (_) -> t_integer() end, Opaques); % address type(hipe_bifs, get_fe, 2, Xs, Opaques) -> strict(hipe_bifs, get_fe, 2, Xs, fun (_) -> t_integer() end, Opaques); type(hipe_bifs, get_rts_param, 1, Xs, Opaques) -> @@ -1081,9 +1092,6 @@ type(hipe_bifs, get_rts_param, 1, Xs, Opaques) -> type(hipe_bifs, invalidate_funinfo_native_addresses, 1, Xs, Opaques) -> strict(hipe_bifs, invalidate_funinfo_native_addresses, 1, Xs, fun (_) -> t_nil() end, Opaques); -%% type(hipe_bifs, make_native_stub, 2, Xs, Opaques) -> -%% strict(hipe_bifs, make_native_stub, 2, Xs, -%% fun (_) -> t_integer() end, Opaques); % address type(hipe_bifs, mark_referred_from, 1, Xs, Opaques) -> strict(hipe_bifs, mark_referred_from, 1, Xs, fun (_) -> t_nil() end, Opaques); @@ -1119,8 +1127,8 @@ type(hipe_bifs, set_native_address, 3, Xs, Opaques) -> type(hipe_bifs, set_native_address_in_fe, 2, Xs, Opaques) -> strict(hipe_bifs, set_native_address_in_fe, 2, Xs, fun (_) -> t_atom('true') end, Opaques); -type(hipe_bifs, system_crc, 1, Xs, Opaques) -> - strict(hipe_bifs, system_crc, 1, Xs, fun (_) -> t_crc32() end, Opaques); +type(hipe_bifs, system_crc, 0, _, _Opaques) -> + t_crc32(); type(hipe_bifs, term_to_word, 1, Xs, Opaques) -> strict(hipe_bifs, term_to_word, 1, Xs, fun (_) -> t_integer() end, Opaques); @@ -1341,8 +1349,8 @@ type(lists, foldr, 3, Xs, _Opaques) -> type(lists, foldl, 3, Xs); % same type(lists, keydelete, 3, Xs, Opaques) -> strict(lists, keydelete, 3, Xs, fun ([_, _, L]) -> - Term = t_list_termination(L), - t_sup(Term, erl_types:lift_list_to_pos_empty(L)) + Term = t_list_termination(L, Opaques), + t_sup(Term, erl_types:lift_list_to_pos_empty(L, Opaques)) end, Opaques); type(lists, keyfind, 3, Xs, Opaques) -> strict(lists, keyfind, 3, Xs, @@ -1891,7 +1899,11 @@ infinity_add(neg_inf, _Number) -> neg_inf; infinity_add(_Number, pos_inf) -> pos_inf; infinity_add(_Number, neg_inf) -> neg_inf; infinity_add(Number1, Number2) when is_integer(Number1), is_integer(Number2) -> - Number1 + Number2. + try Number1 + Number2 + catch + error:system_limit when Number1 < 0 -> neg_inf; + error:system_limit -> pos_inf + end. infinity_mult(neg_inf, Number) -> Greater = infinity_geq(Number, 0), @@ -1902,7 +1914,13 @@ infinity_mult(pos_inf, Number) -> infinity_inv(infinity_mult(neg_inf, Number)); infinity_mult(Number, pos_inf) -> infinity_inv(infinity_mult(neg_inf, Number)); infinity_mult(Number, neg_inf) -> infinity_mult(neg_inf, Number); infinity_mult(Number1, Number2) when is_integer(Number1), is_integer(Number2)-> - Number1 * Number2. + try Number1 * Number2 + catch + error:system_limit -> + if (Number1 >= 0) =:= (Number2 >= 0) -> pos_inf; + true -> neg_inf + end + end. width({Min, Max}) -> infinity_max([width(Min), width(Max)]); width(pos_inf) -> pos_inf; @@ -1922,7 +1940,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 -> @@ -1932,6 +1950,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)], @@ -2160,7 +2200,7 @@ type_ranks(Type, I, Min, Max, [TypeClass|Rest], Opaques) -> type_order() -> [t_number(), t_atom(), t_reference(), t_fun(), t_port(), t_pid(), t_tuple(), - t_list(), t_binary()]. + t_map(), t_list(), t_bitstr()]. key_comparisons_fail(X0, KeyPos, TupleList, Opaques) -> X = case t_is_number(t_inf(X0, t_number(), Opaques), Opaques) of @@ -2260,7 +2300,7 @@ arg_types(erlang, bit_size, 1) -> [t_bitstr()]; %% Guard bif, needs to be here. arg_types(erlang, byte_size, 1) -> - [t_binary()]; + [t_bitstr()]; arg_types(erlang, disconnect_node, 1) -> [t_node()]; arg_types(erlang, halt, 0) -> @@ -2333,6 +2373,8 @@ arg_types(erlang, length, 1) -> %% Guard bif, needs to be here. arg_types(erlang, map_size, 1) -> [t_map()]; +arg_types(erlang, make_fun, 3) -> + [t_atom(), t_atom(), t_arity()]; arg_types(erlang, make_tuple, 2) -> [t_non_neg_fixnum(), t_any()]; % the value 0 is OK as first argument arg_types(erlang, make_tuple, 3) -> @@ -2452,16 +2494,12 @@ arg_types(hipe_bifs, find_na_or_make_stub, 2) -> [t_mfa(), t_boolean()]; arg_types(hipe_bifs, fun_to_address, 1) -> [t_mfa()]; -%% arg_types(hipe_bifs, get_emu_address, 1) -> -%% [t_mfa()]; arg_types(hipe_bifs, get_fe, 2) -> [t_atom(), t_tuple([t_integer(), t_integer(), t_integer()])]; arg_types(hipe_bifs, get_rts_param, 1) -> [t_fixnum()]; arg_types(hipe_bifs, invalidate_funinfo_native_addresses, 1) -> [t_list(t_mfa())]; -%% arg_types(hipe_bifs, make_native_stub, 2) -> -%% [t_integer(), t_arity()]; arg_types(hipe_bifs, mark_referred_from, 1) -> [t_mfa()]; arg_types(hipe_bifs, merge_term, 1) -> @@ -2490,8 +2528,8 @@ arg_types(hipe_bifs, set_native_address, 3) -> [t_mfa(), t_integer(), t_boolean()]; arg_types(hipe_bifs, set_native_address_in_fe, 2) -> [t_integer(), t_integer()]; -arg_types(hipe_bifs, system_crc, 1) -> - [t_crc32()]; +arg_types(hipe_bifs, system_crc, 0) -> + []; arg_types(hipe_bifs, term_to_word, 1) -> [t_any()]; arg_types(hipe_bifs, update_code_size, 3) -> @@ -2633,7 +2671,9 @@ opaque_args(M, F, A, Xs, Opaques) -> true -> case t_tuple_subtypes(X, Opaques) of unknown -> false; - List when length(List) >= 1 -> opaque_recargs(List, Y, Opaques) + List when length(List) >= 1 -> + (t_is_atom(Y, Opaques) andalso + opaque_recargs(List, Y, Opaques)) end; false -> t_has_opaque_subtype(X, Opaques) end]; |